mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-19 05:31:38 +01:00
added item shop, nerf lootbox, fix bugs
This commit is contained in:
33
README.md
33
README.md
@@ -64,6 +64,8 @@ When using/giving an item or qbucks the itemlock will be set at the start of the
|
|||||||
Admins can toggle the itemlock on chatters with the [`itemlock`](#administrative-commands) command. This will stop a chatter from giving, receiving and using items and qweribucks.
|
Admins can toggle the itemlock on chatters with the [`itemlock`](#administrative-commands) command. This will stop a chatter from giving, receiving and using items and qweribucks.
|
||||||
It will NOT stop them from using items by cheering, but if that cheer item usage fails, they will not be given an equivalent item as compensation.
|
It will NOT stop them from using items by cheering, but if that cheer item usage fails, they will not be given an equivalent item as compensation.
|
||||||
|
|
||||||
|
The only ways to get items is through the `getloot` command or by buying them with qbucks.
|
||||||
|
|
||||||
Items can be used with the alias as a command (example: `blast qwerinope`) or with the [`use` command](#qweribucksitem-commands).
|
Items can be used with the alias as a command (example: `blast qwerinope`) or with the [`use` command](#qweribucksitem-commands).
|
||||||
|
|
||||||
When an Item is used it is removed from the inventory of the chatter.
|
When an Item is used it is removed from the inventory of the chatter.
|
||||||
@@ -78,10 +80,10 @@ ITEM|RATE
|
|||||||
`grenade`|`1/5`
|
`grenade`|`1/5`
|
||||||
`blaster`|`1/5`
|
`blaster`|`1/5`
|
||||||
`tnt`|`1/20`
|
`tnt`|`1/20`
|
||||||
`silver bullet`|`1/250`
|
`silver bullet`|`1/1000`
|
||||||
|
|
||||||
Each of these rates get pulled 5 times, then the result is added to your inventory.
|
Each of these rates get pulled 3 times, then the result is added to your inventory.
|
||||||
It's theoretically possible to get 5 of each item.
|
It's theoretically possible to get 3 of each item.
|
||||||
|
|
||||||
### Chatterbot/streamerbot
|
### Chatterbot/streamerbot
|
||||||
|
|
||||||
@@ -104,24 +106,25 @@ COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
|
|||||||
`seiso`|Get a seiso rating|anyone|`seiso`|:white_check_mark:
|
`seiso`|Get a seiso rating|anyone|`seiso`|:white_check_mark:
|
||||||
`backshot`|'Backshot' a random previous chatter|anyone|`backshot`|:white_check_mark:
|
`backshot`|'Backshot' a random previous chatter|anyone|`backshot`|:white_check_mark:
|
||||||
`roulette`|Play russian roulette for a 5 minute timeout|anyone|`roulette`|:white_check_mark:
|
`roulette`|Play russian roulette for a 5 minute timeout|anyone|`roulette`|:white_check_mark:
|
||||||
`timeout {target}`|Times targeted user out for 60 seconds (costs 100 qweribucks)|anyone|`timeout`|:white_check_mark:
|
|
||||||
`stats [target]`|Get timeout and some item stats for yourself or specified user this month|anyone|`stats` `monthlystats`|:white_check_mark:
|
`stats [target]`|Get timeout and some item stats for yourself or specified user this month|anyone|`stats` `monthlystats`|:white_check_mark:
|
||||||
`alltime [target]`|Get timeout and some item stats for yourself or specified user of all time|anyone|`alltime` `alltimestats`|:white_check_mark:
|
`alltime [target]`|Get timeout and some item stats for yourself or specified user of all time|anyone|`alltime` `alltimestats`|:white_check_mark:
|
||||||
|
`monthlyleaderboard`|Get the K/D leaderboard for this month [(info)](#leaderboards)|anyone|`monthlyleaderboard` `kdleaderboard` `leaderboard`|:white_check_mark:
|
||||||
|
`alltimeleaderboard`|Get the K/D leaderboard of all time [(info)](#leaderboards)|anyone|`alltimeleaderboard` `alltimekdleaderboard`|:white_check_mark:
|
||||||
|
`qbucksleaderboard`|Get the current qbucks leaderboard [(info)](#leaderboards)|anyone|`qbucksleaderboard` `moneyleaderboard` `baltop`|:white_check_mark:
|
||||||
|
|
||||||
### Qweribucks/Item commands
|
### Qweribucks/Item commands
|
||||||
|
|
||||||
COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
|
COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
|
||||||
-|-|-|-|-
|
-|-|-|-|-
|
||||||
`getloot`|Get a random assortment of items and qbucks every 10 minutes. [(drop rates)](#lootbox)|anyone|`getloot` `loot` `dig`|:white_check_mark:
|
`getloot`|Get a random assortment of items and qbucks every 10 minutes. [(drop rates)](#lootbox)|anyone|`getloot` `loot` `dig`|:white_check_mark:
|
||||||
`getbalance [target]`|Get balance of target or self|anyone|`getbalance` `balance` `qbucks` `qweribucks` `wallet` `getwallet`|:white_check_mark:
|
|
||||||
`donate {target} {amount}`|Give the targeted user some or all of your qweribucks|anyone|`donate`|:white_check_mark:
|
|
||||||
`iteminfo {item}`|Get item function and aliases|anyone|`iteminfo` `itemhelp` `info`|:white_check_mark:
|
`iteminfo {item}`|Get item function and aliases|anyone|`iteminfo` `itemhelp` `info`|:white_check_mark:
|
||||||
`inventory [target]`|Get inventory contents of target or self|anyone|`inventory` `inv` `pocket`|:white_check_mark:
|
`inventory [target]`|Get inventory contents of target or self|anyone|`inventory` `inv` `pocket`|:white_check_mark:
|
||||||
|
`getprices`|Get the current price of items in the shop|anyone|`getprices` `prices` `shop`|:white_check_mark:
|
||||||
|
`buyitem {item} [amount]`|Buy one or more items for some qbucks. Prices are [here](#items)|anyone|`buyitem` `buy` `purchase`|:white_check_mark:
|
||||||
|
`getbalance [target]`|Get balance of target or self|anyone|`getbalance` `balance` `qbucks` `qweribucks` `wallet` `getwallet`|:white_check_mark:
|
||||||
`give {target} {item} {amount}`|Give targeted user amount of items|anyone|`give`|:white_check_mark:
|
`give {target} {item} {amount}`|Give targeted user amount of items|anyone|`give`|:white_check_mark:
|
||||||
|
`donate {target} {amount}`|Give the targeted user some or all of your qweribucks|anyone|`donate`|:white_check_mark:
|
||||||
`use {item} ...`|Use item. More info at [The items section](#items)|anyone|`use`|:x:
|
`use {item} ...`|Use item. More info at [The items section](#items)|anyone|`use`|:x:
|
||||||
`monthlyleaderboard`|Get the K/D leaderboard for this month [(info)](#leaderboards)|anyone|`monthlyleaderboard` `kdleaderboard` `leaderboard`|:white_check_mark:
|
|
||||||
`alltimeleaderboard`|Get the K/D leaderboard of all time [(info)](#leaderboards)|anyone|`alltimeleaderboard` `alltimekdleaderboard`|:white_check_mark:
|
|
||||||
`qbucksleaderboard`|Get the current qbucks leaderboard [(info)](#leaderboards)|anyone|`qbucksleaderboard` `moneyleaderboard` `baltop`|:white_check_mark:
|
|
||||||
`admindonate {target} {amount}`|Gives the targeted user amount of qweribucks|admins|`admindonate`|:white_check_mark:
|
`admindonate {target} {amount}`|Gives the targeted user amount of qweribucks|admins|`admindonate`|:white_check_mark:
|
||||||
`admingive {target} {item} {amount}`|Give targeted user amount of new items|admins|`admingive`|:white_check_mark:
|
`admingive {target} {item} {amount}`|Give targeted user amount of new items|admins|`admingive`|:white_check_mark:
|
||||||
|
|
||||||
@@ -149,12 +152,12 @@ COMMAND|FUNCTION|USER|ALIASES|DISABLEABLE
|
|||||||
|
|
||||||
## Items
|
## Items
|
||||||
|
|
||||||
NAME|COMMAND|FUNCTION|ALIASES
|
NAME|COMMAND|FUNCTION|ALIASES|COST
|
||||||
-|-|-|-
|
-|-|-|-|-
|
||||||
Blaster|`blaster {target}`|Times targeted user out for 60 seconds|`blaster` `blast`
|
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}`
|
Silver Bullet|`silverbullet {target}`|Times targeted user out for 24 hours|`silverbullet` `execute` `{blastin}`|6666
|
||||||
Grenade|`grenade`|Times a random vulnerable chatter out for 60 seconds|`grenade`
|
Grenade|`grenade`|Times a random vulnerable chatter out for 60 seconds|`grenade`|99
|
||||||
TNT|`tnt`|Give 5-10 random chatters 60 second timeouts|`tnt`
|
TNT|`tnt`|Give 5-10 random chatters 60 second timeouts|`tnt`|1000
|
||||||
|
|
||||||
## Cheers
|
## Cheers
|
||||||
|
|
||||||
|
|||||||
@@ -31,14 +31,12 @@ export default cheers;
|
|||||||
export { namedcheers };
|
export { namedcheers };
|
||||||
|
|
||||||
import { sendMessage } from 'commands';
|
import { sendMessage } from 'commands';
|
||||||
import logger from 'lib/logger';
|
|
||||||
import { getUserRecord } from 'db/dbUser';
|
import { getUserRecord } from 'db/dbUser';
|
||||||
import { changeItemCount, type items } from 'items';
|
import { changeItemCount, type items } from 'items';
|
||||||
|
|
||||||
export async function handleNoTarget(msg: EventSubChannelChatMessageEvent, user: User, itemname: items, silent = true) {
|
export async function handleNoTarget(msg: EventSubChannelChatMessageEvent, user: User, itemname: items, silent = true) {
|
||||||
if (await user.itemLock()) {
|
if (await user.itemLock()) {
|
||||||
await sendMessage(`Cannot give ${user.displayName} a ${itemname}`, msg.messageId);
|
await sendMessage(`Cannot give ${user.displayName} a ${itemname} (itemlock)`, msg.messageId);
|
||||||
logger.err(`Failed to give ${user.displayName} a ${itemname} for their cheer`);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
await user.setLock();
|
await user.setLock();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default new Command({
|
|||||||
if (!args[1]) { await sendMessage('Please specify the amount qweribucks you want to give', msg.messageId); return; };
|
if (!args[1]) { await sendMessage('Please specify the amount qweribucks you want to give', msg.messageId); return; };
|
||||||
const amount = parseInt(args[1]);
|
const amount = parseInt(args[1]);
|
||||||
if (isNaN(amount)) { await sendMessage(`'${args[1]}' is not a valid amount`); return; };
|
if (isNaN(amount)) { await sendMessage(`'${args[1]}' is not a valid amount`); return; };
|
||||||
if (await target.itemLock()) { await sendMessage('Cannot give qweribucks: item lock is set', msg.messageId); return; };
|
if (await target.itemLock()) { await sendMessage('Cannot give qweribucks (itemlock)', msg.messageId); return; };
|
||||||
await target.setLock();
|
await target.setLock();
|
||||||
const data = await changeBalance(target, userRecord, amount);
|
const data = await changeBalance(target, userRecord, amount);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default new Command({
|
|||||||
if (!args[2]) { await sendMessage('Please specify the amount of the item you want to give', msg.messageId); return; };
|
if (!args[2]) { await sendMessage('Please specify the amount of the item you want to give', msg.messageId); return; };
|
||||||
const amount = parseInt(args[2]);
|
const amount = parseInt(args[2]);
|
||||||
if (isNaN(amount)) { await sendMessage(`'${args[2]}' is not a valid amount`); return; };
|
if (isNaN(amount)) { await sendMessage(`'${args[2]}' is not a valid amount`); return; };
|
||||||
if (await target.itemLock()) { await sendMessage('Cannot give item: item lock is set', msg.messageId); return; };
|
if (await target.itemLock()) { await sendMessage('Cannot give item (itemlock)', msg.messageId); return; };
|
||||||
await target.setLock();
|
await target.setLock();
|
||||||
const data = await changeItemCount(target, userRecord, item.name, amount);
|
const data = await changeItemCount(target, userRecord, item.name, amount);
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|||||||
37
src/commands/buyitem.ts
Normal file
37
src/commands/buyitem.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { Command, sendMessage } from "commands";
|
||||||
|
import parseCommandArgs from "lib/parseCommandArgs";
|
||||||
|
import items from "items";
|
||||||
|
import { getUserRecord, updateUserRecord } from "db/dbUser";
|
||||||
|
|
||||||
|
export default new Command({
|
||||||
|
name: 'buyitem',
|
||||||
|
aliases: ['buyitem', 'buy', 'purchase'],
|
||||||
|
usertype: 'chatter',
|
||||||
|
execution: async (msg, user) => {
|
||||||
|
const args = parseCommandArgs(msg.messageText);
|
||||||
|
if (!args[0]) { await sendMessage(`Specify the item you'd like to buy`, msg.messageId); return; };
|
||||||
|
const selecteditem = items.get(args[0].toLowerCase());
|
||||||
|
if (!selecteditem) { await sendMessage(`'${args[0]}' is not a valid item`, msg.messageId); return; };
|
||||||
|
const amount = args[1] ? parseInt(args[1]) : 1;
|
||||||
|
if (isNaN(amount) || amount < 1) { await sendMessage(`'${args[1]}' is not a valid amount to buy`, msg.messageId); return; };
|
||||||
|
const totalcost = amount * selecteditem.price;
|
||||||
|
|
||||||
|
if (await user.itemLock()) { await sendMessage('Cannot buy item (itemlock)', msg.messageId); return; };
|
||||||
|
await user.setLock();
|
||||||
|
|
||||||
|
const userRecord = await getUserRecord(user);
|
||||||
|
if (userRecord.balance < totalcost) { await sendMessage(`You don't have enough qbucks to buy ${amount} ${selecteditem.prettyName}${amount === 1 ? '' : selecteditem.plural}! You have ${userRecord.balance}, need ${totalcost}`); await user.clearLock(); return; };
|
||||||
|
|
||||||
|
if (userRecord.inventory[selecteditem.name]) userRecord.inventory[selecteditem.name]! += amount
|
||||||
|
else userRecord.inventory[selecteditem.name] = amount;
|
||||||
|
|
||||||
|
userRecord.balance -= totalcost;
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
updateUserRecord(user, userRecord),
|
||||||
|
sendMessage(`${user.displayName} bought ${amount} ${selecteditem.prettyName}${amount === 1 ? '' : selecteditem.plural} for ${totalcost} qbucks. They now have ${userRecord.inventory[selecteditem.name]} ${selecteditem.prettyName}${userRecord.inventory[selecteditem.name] === 1 ? '' : selecteditem.plural} and ${userRecord.balance} qbucks`, msg.messageId)
|
||||||
|
]);
|
||||||
|
|
||||||
|
await user.clearLock();
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Command, sendMessage } from "commands";
|
import { Command, sendMessage } from "commands";
|
||||||
import type { userRecord } from "db/connection";
|
|
||||||
import { getUserRecord } from "db/dbUser";
|
import { getUserRecord } from "db/dbUser";
|
||||||
import parseCommandArgs from "lib/parseCommandArgs";
|
import parseCommandArgs from "lib/parseCommandArgs";
|
||||||
import { changeBalance } from "lib/changeBalance";
|
import { changeBalance } from "lib/changeBalance";
|
||||||
@@ -24,7 +23,7 @@ export default new Command({
|
|||||||
const userRecord = await getUserRecord(user);
|
const userRecord = await getUserRecord(user);
|
||||||
if (userRecord.balance < amount) { await sendMessage(`You can't give qweribucks you don't have!`, msg.messageId); return; };
|
if (userRecord.balance < amount) { await sendMessage(`You can't give qweribucks you don't have!`, msg.messageId); return; };
|
||||||
|
|
||||||
if (await user.itemLock() || await target.itemLock()) { await sendMessage('Cannot give qweribucks', msg.messageId); return; };
|
if (await user.itemLock() || await target.itemLock()) { await sendMessage('Cannot give qweribucks (itemlock)', msg.messageId); return; };
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
user.setLock(),
|
user.setLock(),
|
||||||
@@ -37,7 +36,7 @@ export default new Command({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if (!data.includes(false)) {
|
if (!data.includes(false)) {
|
||||||
const { balance: newamount } = data[0] as userRecord;
|
const { balance: newamount } = data[0];
|
||||||
await sendMessage(`${user.displayName} gave ${amount} qweribuck${amount === 1 ? '' : 's'} to ${target.displayName}. They now have ${newamount} qweribuck${newamount === 1 ? '' : 's'}`, msg.messageId);
|
await sendMessage(`${user.displayName} gave ${amount} qweribuck${amount === 1 ? '' : 's'} to ${target.displayName}. They now have ${newamount} qweribuck${newamount === 1 ? '' : 's'}`, msg.messageId);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Rewrite this section
|
// TODO: Rewrite this section
|
||||||
|
|||||||
@@ -49,14 +49,13 @@ export default new Command({
|
|||||||
grenade: 0,
|
grenade: 0,
|
||||||
blaster: 0,
|
blaster: 0,
|
||||||
tnt: 0,
|
tnt: 0,
|
||||||
silverbullet: 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
if (Math.floor(Math.random() * 5) === 0) itemDiff.grenade! += 1;
|
if (Math.floor(Math.random() * 5) === 0) itemDiff.grenade! += 1;
|
||||||
if (Math.floor(Math.random() * 5) === 0) itemDiff.blaster! += 1;
|
if (Math.floor(Math.random() * 5) === 0) itemDiff.blaster! += 1;
|
||||||
if (Math.floor(Math.random() * 25) === 0) itemDiff.tnt! += 1;
|
if (Math.floor(Math.random() * 25) === 0) itemDiff.tnt! += 1;
|
||||||
if (Math.floor(Math.random() * 250) === 0) itemDiff.silverbullet! += 1;
|
if (Math.floor(Math.random() * 1000) === 0) itemDiff.silverbullet! += 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [item, amount] of Object.entries(itemDiff) as [items, number][]) {
|
for (const [item, amount] of Object.entries(itemDiff) as [items, number][]) {
|
||||||
|
|||||||
12
src/commands/getprices.ts
Normal file
12
src/commands/getprices.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Command, sendMessage } from "commands";
|
||||||
|
import { itemObjectArray } from "items";
|
||||||
|
|
||||||
|
export default new Command({
|
||||||
|
name: 'getprices',
|
||||||
|
aliases: ['getprices', 'prices', 'shop'],
|
||||||
|
usertype: 'chatter',
|
||||||
|
execution: async msg => {
|
||||||
|
const txt = itemObjectArray.toSorted((a, b) => a.price - b.price).map(item => `${item.prettyName}: ${item.price}`);
|
||||||
|
await sendMessage(`Prices: ${txt.join(' | ')}`, msg.messageId);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Command, sendMessage } from "commands";
|
import { Command, sendMessage } from "commands";
|
||||||
import type { userRecord } from "db/connection";
|
|
||||||
import { getUserRecord } from "db/dbUser";
|
import { getUserRecord } from "db/dbUser";
|
||||||
import items, { changeItemCount } from "items";
|
import items, { changeItemCount } from "items";
|
||||||
import parseCommandArgs from "lib/parseCommandArgs";
|
import parseCommandArgs from "lib/parseCommandArgs";
|
||||||
@@ -26,7 +25,7 @@ export default new Command({
|
|||||||
const userRecord = await getUserRecord(user);
|
const userRecord = await getUserRecord(user);
|
||||||
if (userRecord.inventory[item.name]! < amount) { await sendMessage(`You can't give items you don't have!`, msg.messageId); return; };
|
if (userRecord.inventory[item.name]! < amount) { await sendMessage(`You can't give items you don't have!`, msg.messageId); return; };
|
||||||
|
|
||||||
if (await user.itemLock() || await target.itemLock()) { await sendMessage('Cannot give item', msg.messageId); return; };
|
if (await user.itemLock() || await target.itemLock()) { await sendMessage('Cannot give item (itemlock)', msg.messageId); return; };
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
user.setLock(),
|
user.setLock(),
|
||||||
@@ -38,14 +37,14 @@ export default new Command({
|
|||||||
await changeItemCount(user, userRecord, item.name, -amount)
|
await changeItemCount(user, userRecord, item.name, -amount)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!data.includes(false)) {
|
if (data[0] !== false && data[1] !== false) {
|
||||||
const tempdata = data[0] as userRecord;
|
const tempdata = data[0];
|
||||||
const newamount = tempdata.inventory[item.name]!;
|
const newamount = tempdata.inventory[item.name]!;
|
||||||
await sendMessage(`${user.displayName} gave ${amount} ${item.prettyName + (amount === 1 ? '' : item.plural)} to ${target.displayName}. They now have ${newamount} ${item.prettyName + (newamount === 1 ? '' : item.plural)}`, msg.messageId);
|
await sendMessage(`${user.displayName} gave ${amount} ${item.prettyName + (amount === 1 ? '' : item.plural)} to ${target.displayName}. They now have ${newamount} ${item.prettyName + (newamount === 1 ? '' : item.plural)}`, msg.messageId);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Rewrite this section
|
// TODO: Rewrite this section
|
||||||
await sendMessage(`Failed to give ${target.displayName} ${amount} ${item.prettyName + (amount === 1 ? '' : item.plural)}`, msg.messageId);
|
await sendMessage(`Failed to give ${target.displayName} ${amount} ${item.prettyName + (amount === 1 ? '' : item.plural)}`, msg.messageId);
|
||||||
logger.warn(`WARNING: Item donation failed: target success: ${data[0] !== false}, donator success: ${data[1] !== false}`);
|
logger.warn(`WARNING: Item donation failed: target success: ${data[0] !== false ? "yes" : "no"}, donator success: ${data[1] !== false ? "yes" : "no"}`);
|
||||||
};
|
};
|
||||||
await user.clearLock();
|
await user.clearLock();
|
||||||
await target.clearLock();
|
await target.clearLock();
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
import { Command, sendMessage } from "commands";
|
|
||||||
import { getUserRecord } from "db/dbUser";
|
|
||||||
import parseCommandArgs from "lib/parseCommandArgs";
|
|
||||||
import User from "user";
|
|
||||||
import { timeout } from "lib/timeout";
|
|
||||||
import { changeBalance } from "lib/changeBalance";
|
|
||||||
import { createTimeoutRecord } from "db/dbTimeouts";
|
|
||||||
|
|
||||||
export default new Command({
|
|
||||||
name: 'timeout',
|
|
||||||
aliases: ['timeout'],
|
|
||||||
usertype: 'chatter',
|
|
||||||
execution: async (msg, user) => {
|
|
||||||
const userObj = await getUserRecord(user);
|
|
||||||
if (userObj.balance < 100) { await sendMessage(`You don't have enough qweribucks (need 100, have ${userObj.balance})`, msg.messageId); return; };
|
|
||||||
const messagequery = parseCommandArgs(msg.messageText);
|
|
||||||
if (!messagequery[0]) { await sendMessage('Please specify a target'); return; };
|
|
||||||
const target = await User.initUsername(messagequery[0].toLowerCase());
|
|
||||||
if (!target) { await sendMessage(`${messagequery[0]} doesn't exist`); return; };
|
|
||||||
await getUserRecord(target); // make sure the user record exist in the database
|
|
||||||
|
|
||||||
const result = await timeout(target, `You got BLASTED by ${user.displayName}`, 60);
|
|
||||||
if (result.status) {
|
|
||||||
await Promise.all([
|
|
||||||
sendMessage(`GOTTEM ${target.displayName} got BLASTED by ${user.displayName} GOTTEM`),
|
|
||||||
changeBalance(user, userObj, -100),
|
|
||||||
createTimeoutRecord(user, target, 'blaster')
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
switch (result.reason) {
|
|
||||||
case "banned":
|
|
||||||
await sendMessage(`${target.displayName} is already timed out/banned`, msg.messageId);
|
|
||||||
break;
|
|
||||||
case "illegal":
|
|
||||||
await Promise.all([
|
|
||||||
sendMessage(`${user.displayName} Nou Nou Nou`),
|
|
||||||
timeout(user, 'nah', 60)
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
case "unknown":
|
|
||||||
await sendMessage('Something went wrong...', msg.messageId);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -16,17 +16,20 @@ export default new Item({
|
|||||||
plural: 's',
|
plural: 's',
|
||||||
description: 'Times a specific person out for 60 seconds',
|
description: 'Times a specific person out for 60 seconds',
|
||||||
aliases: ['blaster', 'blast'],
|
aliases: ['blaster', 'blast'],
|
||||||
|
price: 100,
|
||||||
execution: async (msg, user) => {
|
execution: async (msg, user) => {
|
||||||
const userObj = await getUserRecord(user);
|
|
||||||
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any blasters!`, msg.messageId); return; };
|
|
||||||
const messagequery = parseCommandArgs(msg.messageText);
|
const messagequery = parseCommandArgs(msg.messageText);
|
||||||
if (!messagequery[0]) { await sendMessage('Please specify a target'); return; };
|
if (!messagequery[0]) { await sendMessage('Please specify a target'); return; };
|
||||||
const target = await User.initUsername(messagequery[0].toLowerCase());
|
const target = await User.initUsername(messagequery[0].toLowerCase());
|
||||||
if (!target) { await sendMessage(`${messagequery[0]} doesn't exist`); return; };
|
if (!target) { await sendMessage(`${messagequery[0]} doesn't exist`); return; };
|
||||||
await getUserRecord(target); // make sure the user record exist in the database
|
await getUserRecord(target); // make sure the user record exist in the database
|
||||||
|
|
||||||
if (await user.itemLock()) { await sendMessage('Cannot use an item right now', msg.messageId); return; };
|
if (await user.itemLock()) { await sendMessage('Cannot use an item (itemlock)', msg.messageId); return; };
|
||||||
await user.setLock();
|
await user.setLock();
|
||||||
|
|
||||||
|
const userObj = await getUserRecord(user);
|
||||||
|
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any blasters!`, msg.messageId); await user.clearLock(); return; };
|
||||||
|
|
||||||
const result = await timeout(target, `You got blasted by ${user.displayName}!`, 60);
|
const result = await timeout(target, `You got blasted by ${user.displayName}!`, 60);
|
||||||
if (result.status) await Promise.all([
|
if (result.status) await Promise.all([
|
||||||
sendMessage(`GOTTEM ${target.displayName} got BLASTED by ${user.displayName} GOTTEM`),
|
sendMessage(`GOTTEM ${target.displayName} got BLASTED by ${user.displayName} GOTTEM`),
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ export default new Item({
|
|||||||
plural: 's',
|
plural: 's',
|
||||||
description: 'Give a random chatter a 60s timeout',
|
description: 'Give a random chatter a 60s timeout',
|
||||||
aliases: ['grenade'],
|
aliases: ['grenade'],
|
||||||
|
price: 99,
|
||||||
execution: async (msg, user) => {
|
execution: async (msg, user) => {
|
||||||
const userObj = await getUserRecord(user);
|
|
||||||
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any grenades!`, msg.messageId); return; };
|
|
||||||
const targets = await redis.keys(`user:*:vulnerable`);
|
const targets = await redis.keys(`user:*:vulnerable`);
|
||||||
if (targets.length === 0) { await sendMessage('No vulnerable chatters to blow up', msg.messageId); return; };
|
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 selection = targets[Math.floor(Math.random() * targets.length)]!;
|
||||||
@@ -26,8 +25,12 @@ export default new Item({
|
|||||||
|
|
||||||
await getUserRecord(target!); // make sure the user record exist in the database
|
await getUserRecord(target!); // make sure the user record exist in the database
|
||||||
|
|
||||||
if (await user.itemLock()) { await sendMessage('Cannot use an item right now', msg.messageId); return; };
|
if (await user.itemLock()) { await sendMessage('Cannot use an item (itemlock)', msg.messageId); return; };
|
||||||
await user.setLock();
|
await user.setLock();
|
||||||
|
|
||||||
|
const userObj = await getUserRecord(user);
|
||||||
|
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any grenades!`, msg.messageId); await user.clearLock(); return; };
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
timeout(target!, `You got hit by ${user.displayName}'s grenade!`, 60),
|
timeout(target!, `You got hit by ${user.displayName}'s grenade!`, 60),
|
||||||
sendMessage(`wybuh ${target?.displayName} got hit by ${user.displayName}'s grenade wybuh`),
|
sendMessage(`wybuh ${target?.displayName} got hit by ${user.displayName}'s grenade wybuh`),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ type itemOptions = {
|
|||||||
description: string;
|
description: string;
|
||||||
execution: (message: EventSubChannelChatMessageEvent, sender: User, args?: specialExecuteArgs) => Promise<void>;
|
execution: (message: EventSubChannelChatMessageEvent, sender: User, args?: specialExecuteArgs) => Promise<void>;
|
||||||
specialaliases?: string[];
|
specialaliases?: string[];
|
||||||
|
price: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Item {
|
export class Item {
|
||||||
@@ -20,6 +21,7 @@ export class Item {
|
|||||||
public readonly aliases: string[];
|
public readonly aliases: string[];
|
||||||
public readonly specialaliases: string[];
|
public readonly specialaliases: string[];
|
||||||
public readonly usertype: userType;
|
public readonly usertype: userType;
|
||||||
|
public readonly price: number;
|
||||||
public readonly execute: (message: EventSubChannelChatMessageEvent, sender: User, args?: specialExecuteArgs) => Promise<void>;
|
public readonly execute: (message: EventSubChannelChatMessageEvent, sender: User, args?: specialExecuteArgs) => Promise<void>;
|
||||||
public readonly disableable: boolean;
|
public readonly disableable: boolean;
|
||||||
|
|
||||||
@@ -34,12 +36,14 @@ export class Item {
|
|||||||
this.execute = options.execution;
|
this.execute = options.execution;
|
||||||
this.disableable = true;
|
this.disableable = true;
|
||||||
this.specialaliases = options.specialaliases ?? [];
|
this.specialaliases = options.specialaliases ?? [];
|
||||||
|
this.price = options.price;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
import { readdir } from 'node:fs/promises';
|
import { readdir } from 'node:fs/promises';
|
||||||
import { updateUserRecord, type inventoryUpdate } from "db/dbUser";
|
import { updateUserRecord, type inventoryUpdate } from "db/dbUser";
|
||||||
const itemMap = new Map<string, Item>;
|
const itemAliasMap = new Map<string, Item>;
|
||||||
|
const itemObjectArray: Item[] = []
|
||||||
const specialAliasItems = new Map<string, Item>;
|
const specialAliasItems = new Map<string, Item>;
|
||||||
const emptyInventory: inventory = {};
|
const emptyInventory: inventory = {};
|
||||||
const itemarray: items[] = [];
|
const itemarray: items[] = [];
|
||||||
@@ -51,16 +55,17 @@ for (const file of files) {
|
|||||||
const item: Item = await import(import.meta.dir + '/' + file.slice(0, -3)).then(a => a.default);
|
const item: Item = await import(import.meta.dir + '/' + file.slice(0, -3)).then(a => a.default);
|
||||||
emptyInventory[item.name] = 0;
|
emptyInventory[item.name] = 0;
|
||||||
itemarray.push(item.name);
|
itemarray.push(item.name);
|
||||||
|
itemObjectArray.push(item);
|
||||||
for (const alias of item.aliases) {
|
for (const alias of item.aliases) {
|
||||||
itemMap.set(alias, item); // Since it's not a primitive type the map is filled with references to the item, not the actual object
|
itemAliasMap.set(alias, item); // Since it's not a primitive type the map is filled with references to the item, not the actual object
|
||||||
};
|
};
|
||||||
for (const alias of item.specialaliases) {
|
for (const alias of item.specialaliases) {
|
||||||
specialAliasItems.set(alias, item);
|
specialAliasItems.set(alias, item);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default itemMap;
|
export default itemAliasMap;
|
||||||
export { emptyInventory, itemarray, specialAliasItems };
|
export { emptyInventory, itemarray, specialAliasItems, itemObjectArray };
|
||||||
|
|
||||||
export type items = "blaster" | "silverbullet" | "grenade" | "tnt";
|
export type items = "blaster" | "silverbullet" | "grenade" | "tnt";
|
||||||
export type inventory = {
|
export type inventory = {
|
||||||
|
|||||||
@@ -17,17 +17,20 @@ export default new Item({
|
|||||||
description: 'Times a specific person out for 24 hours',
|
description: 'Times a specific person out for 24 hours',
|
||||||
aliases: ['execute', 'silverbullet'],
|
aliases: ['execute', 'silverbullet'],
|
||||||
specialaliases: ['blastin'],
|
specialaliases: ['blastin'],
|
||||||
|
price: 6666,
|
||||||
execution: async (msg, user, specialargs) => {
|
execution: async (msg, user, specialargs) => {
|
||||||
const userObj = await getUserRecord(user);
|
|
||||||
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any silver bullets!`, msg.messageId); return; };
|
|
||||||
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; };
|
||||||
const target = await User.initUsername(messagequery[0].toLowerCase());
|
const target = await User.initUsername(messagequery[0].toLowerCase());
|
||||||
if (!target) { await sendMessage(`${messagequery[0]} doesn't exist`); return; };
|
if (!target) { await sendMessage(`${messagequery[0]} doesn't exist`); return; };
|
||||||
await getUserRecord(target); // make sure the user record exist in the database
|
await getUserRecord(target); // make sure the user record exist in the database
|
||||||
|
|
||||||
if (await user.itemLock()) { await sendMessage('Cannot use an item right now', msg.messageId); return; };
|
if (await user.itemLock()) { await sendMessage('Cannot use an item (itemlock)', msg.messageId); return; };
|
||||||
await user.setLock();
|
await user.setLock();
|
||||||
|
|
||||||
|
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; };
|
||||||
|
|
||||||
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 * 60 * 24);
|
||||||
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`),
|
||||||
|
|||||||
@@ -16,16 +16,18 @@ export default new Item({
|
|||||||
plural: 's',
|
plural: 's',
|
||||||
description: 'Give 5-10 random chatters 60 second timeouts',
|
description: 'Give 5-10 random chatters 60 second timeouts',
|
||||||
aliases: ['tnt'],
|
aliases: ['tnt'],
|
||||||
|
price: 1000,
|
||||||
execution: async (msg, user) => {
|
execution: async (msg, user) => {
|
||||||
const userObj = await getUserRecord(user);
|
|
||||||
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any TNTs!`, msg.messageId); return; };
|
|
||||||
const vulntargets = await redis.keys('user:*:vulnerable').then(a => a.map(b => b.slice(5, -11)));
|
const vulntargets = await redis.keys('user:*:vulnerable').then(a => a.map(b => b.slice(5, -11)));
|
||||||
if (vulntargets.length === 0) { await sendMessage('No vulnerable chatters to blow up', msg.messageId); return; };
|
if (vulntargets.length === 0) { await sendMessage('No vulnerable chatters to blow up', msg.messageId); return; };
|
||||||
const targets = getTNTTargets(vulntargets);
|
const targets = getTNTTargets(vulntargets);
|
||||||
|
|
||||||
if (await user.itemLock()) { await sendMessage('Cannot use an item right now', msg.messageId); return; };
|
if (await user.itemLock()) { await sendMessage('Cannot use an item (itemlock)', msg.messageId); return; };
|
||||||
await user.setLock();
|
await user.setLock();
|
||||||
|
|
||||||
|
const userObj = await getUserRecord(user);
|
||||||
|
if (userObj.inventory[ITEMNAME]! < 1) { await sendMessage(`You don't have any TNTs!`, msg.messageId); await user.clearLock(); return; };
|
||||||
|
|
||||||
await Promise.all(targets.map(async targetid => {
|
await Promise.all(targets.map(async targetid => {
|
||||||
const target = await User.initUserId(targetid);
|
const target = await User.initUserId(targetid);
|
||||||
await getUserRecord(target!); // make sure the user record exist in the database
|
await getUserRecord(target!); // make sure the user record exist in the database
|
||||||
|
|||||||
61
src/migrate.ts
Normal file
61
src/migrate.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import PocketBase from "pocketbase";
|
||||||
|
import { type inventory, type items } from "items"
|
||||||
|
const pb = new PocketBase('qweribot-main:8091');
|
||||||
|
import db from "db/connection";
|
||||||
|
import * as schema from "db/schema";
|
||||||
|
|
||||||
|
export type userRecord = {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
balance: number;
|
||||||
|
inventory: inventory;
|
||||||
|
lastlootbox: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type usedItemRecord = {
|
||||||
|
id?: string;
|
||||||
|
user: string;
|
||||||
|
item: items;
|
||||||
|
created: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type timeoutRecord = {
|
||||||
|
id?: string;
|
||||||
|
user: string;
|
||||||
|
target: string;
|
||||||
|
item: items;
|
||||||
|
created: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const pbusers = await pb.collection<userRecord>('users').getFullList();
|
||||||
|
for (const pbuser of pbusers) {
|
||||||
|
await db.insert(schema.users).values({
|
||||||
|
id: parseInt(pbuser.id),
|
||||||
|
username: pbuser.username,
|
||||||
|
balance: pbuser.balance,
|
||||||
|
inventory: pbuser.inventory,
|
||||||
|
lastlootbox: new Date(Date.parse(pbuser.lastlootbox))
|
||||||
|
});
|
||||||
|
console.log(`Migrated users row of ${pbuser.username} to the new database`)
|
||||||
|
};
|
||||||
|
|
||||||
|
const pbuseditems = await pb.collection<usedItemRecord>('usedItems').getFullList();
|
||||||
|
for (const pbuseditem of pbuseditems) {
|
||||||
|
await db.insert(schema.usedItems).values({
|
||||||
|
user: parseInt(pbuseditem.user),
|
||||||
|
item: pbuseditem.item,
|
||||||
|
created: new Date(Date.parse(pbuseditem.created))
|
||||||
|
});
|
||||||
|
console.log(`Migrated usedItem row of user: ${pbuseditem.user} and item: ${pbuseditem.item} to the new database`)
|
||||||
|
};
|
||||||
|
|
||||||
|
const pbtimeouts = await pb.collection<timeoutRecord>('timeouts').getFullList();
|
||||||
|
for (const pbtimeout of pbtimeouts) {
|
||||||
|
await db.insert(schema.timeouts).values({
|
||||||
|
user: parseInt(pbtimeout.user),
|
||||||
|
target: parseInt(pbtimeout.target),
|
||||||
|
item: pbtimeout.item,
|
||||||
|
created: new Date(Date.parse(pbtimeout.created))
|
||||||
|
});
|
||||||
|
console.log(`Migrated timeout row of user: ${pbtimeout.user} shooting user: ${pbtimeout.target} with item: ${pbtimeout.item}`)
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user