improved safety, minor docker compose changes, cheer parsing bugfixes

This commit is contained in:
2025-09-18 15:53:36 +02:00
parent a06b0a1e03
commit 1d9b810229
16 changed files with 36 additions and 31 deletions

View File

@@ -1,7 +1,7 @@
services:
valkey:
image: valkey/valkey:alpine
container_name: valkey
container_name: qweribot-valkey
ports:
- 6379:6379
restart: no
@@ -10,11 +10,11 @@ services:
environment:
- VALKEY_EXTRA_FLAGS=--save 60 1
postgres:
container_name: postgres
container_name: qweribot-postgres
image: postgres:latest
restart: unless-stopped
env_file:
- .env.development
- .env
ports:
- "5432:5432"
volumes:

View File

@@ -45,5 +45,5 @@ export default new Cheer('execute', 6666, async (msg, user) => {
break;
};
};
});
}, true);

View File

@@ -30,4 +30,4 @@ export default new Cheer('grenade', 99, async (msg, user) => {
target: target?.displayName!
})
]);
});
}, true);

View File

@@ -5,10 +5,12 @@ export class Cheer {
public readonly name: string;
public readonly amount: number;
public readonly execute: (msg: EventSubChannelChatMessageEvent, sender: User) => Promise<void>;
constructor(name: string, amount: number, execution: (msg: EventSubChannelChatMessageEvent, sender: User) => Promise<void>) {
public readonly isItem: boolean;
constructor(name: string, amount: number, execution: (msg: EventSubChannelChatMessageEvent, sender: User) => Promise<void>, isItem = false) {
this.name = name.toLowerCase();
this.amount = amount;
this.execute = execution;
this.isItem = isItem;
};
};
@@ -31,9 +33,9 @@ export { namedcheers };
import { sendMessage } from 'commands';
import logger from 'lib/logger';
import { getUserRecord } from 'db/dbUser';
import { changeItemCount } from 'items';
import { changeItemCount, type items } from 'items';
export async function handleNoTarget(msg: EventSubChannelChatMessageEvent, user: User, itemname: string, silent = true) {
export async function handleNoTarget(msg: EventSubChannelChatMessageEvent, user: User, itemname: items, silent = true) {
if (await user.itemLock()) {
await sendMessage(`Cannot give ${user.displayName} a ${itemname}`, msg.messageId);
logger.err(`Failed to give ${user.displayName} a ${itemname} for their cheer`);

View File

@@ -46,4 +46,4 @@ export default new Cheer('timeout', 100, async (msg, user) => {
break;
};
};
});
}, true);

View File

@@ -23,16 +23,18 @@ export default new Cheer('tnt', 1000, async (msg, user) => {
timeout(target!, `You got hit by ${user.displayName}'s TNT!`, 60),
redis.del(`user:${targetid}:vulnerable`),
sendMessage(`wybuh ${target?.displayName} got hit by ${user.displayName}'s TNT wybuh`),
createTimeoutRecord(user, target!, ITEMNAME),
createCheerEventRecord(user, ITEMNAME),
createTimeoutRecord(user, target!, ITEMNAME)
]);
}));
await playAlert({
name: 'tntExplosion',
user: user.displayName,
targets
})
await Promise.all([
createCheerEventRecord(user, ITEMNAME),
playAlert({
name: 'tntExplosion',
user: user.displayName,
targets
})
]);
await sendMessage(`RIPBOZO ${user.displayName} exploded ${targets.length} chatter${targets.length === 1 ? '' : 's'} with their TNT RIPBOZO`);
});
}, true);

View File

@@ -16,7 +16,7 @@ export default new Command({
const userRecord = await getUserRecord(target);
if (!args[1]) { await sendMessage('Please specify the amount qweribucks you want to give', msg.messageId); return; };
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; };
await target.setLock();
const data = await changeBalance(target, userRecord, amount);

View File

@@ -19,7 +19,7 @@ export default new Command({
if (!item) { await sendMessage(`Item ${args[1]} doesn't exist`, 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]);
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; };
await target.setLock();
const data = await changeItemCount(target, userRecord, item.name, amount);

View File

@@ -15,7 +15,7 @@ export default new Command({
const userKDs: KD[] = [];
await Promise.all(users.map(async userRecord => {
const user = await User.initUserId(userRecord.id);
const user = await User.initUserId(userRecord.id.toString());
if (!user) return;
const data = await getTimeoutStats(user, false);
if (!data) return;

View File

@@ -19,7 +19,7 @@ export default new Command({
const targetRecord = await getUserRecord(target);
if (!args[1]) { await sendMessage('Please specify the amount of the item you want to give', msg.messageId); return; };
const amount = parseInt(args[1]);
if (isNaN(amount) || amount < 1) { await sendMessage(`${args[1]} is not a valid amount`); return; };
if (isNaN(amount) || amount < 1) { await sendMessage(`'${args[1]}' is not a valid amount`); return; };
const userRecord = await getUserRecord(user);
if (userRecord.balance < amount) { await sendMessage(`You can't give qweribucks you don't have!`, msg.messageId); return; };

View File

@@ -8,7 +8,7 @@ export default new Command({
execution: async (_msg, user) => {
await Promise.all([
timeout(user, "NO MODME", 60),
sendMessage(`NO MODME COMMAND!!! UltraMad`)
sendMessage(`NO MODME COMMAND!!! UltraMad UltraMad UltraMad`)
]);
}
});

View File

@@ -22,7 +22,7 @@ export default new Command({
if (!item) { await sendMessage(`Item ${args[1]} doesn't exist`, 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]);
if (isNaN(amount) || amount < 1) { await sendMessage(`${args[2]} is not a valid amount`); return; };
if (isNaN(amount) || amount < 1) { await sendMessage(`'${args[2]}' is not a valid amount`); return; };
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; };

View File

@@ -15,7 +15,7 @@ export default new Command({
const userKDs: KD[] = [];
await Promise.all(users.map(async userRecord => {
const user = await User.initUserId(userRecord.id);
const user = await User.initUserId(userRecord.id.toString());
if (!user) return;
const data = await getTimeoutStats(user, true);
if (!data) return;

View File

@@ -14,7 +14,7 @@ export default new Command({
const txt: string[] = [];
for (const userRecord of data) {
if (userRecord.balance === 0) continue;
const user = await User.initUserId(userRecord.id);
const user = await User.initUserId(userRecord.id.toString());
if (!user) continue;
txt.push(`${index}. ${user.displayName}: ${userRecord.balance}`);
index++;

View File

@@ -28,7 +28,7 @@ async function parseChatMessage(msg: EventSubChannelChatMessageEvent) {
// and both are usable to target the same user (id is the same)
// The only problem would be if a user changed their name and someone else took their name right after
if (msg.chatterId === chatterId) return;
if (msg.chatterId === chatterId && chatterId !== streamerId) return;
if (!await redis.exists(`user:${user?.id}:haschatted`) && !msg.sourceMessageId) {
const message = await sendMessage(`Welcome ${user?.displayName}. Please note: This chat has PvP, if you get timed out that's part of the qwerinope experience. You have 10 minutes of invincibility. A full list of commands and items can be found here: https://github.com/qwerinope/qweribot/#qweribot`);
@@ -68,9 +68,7 @@ async function handleChatMessage(msg: EventSubChannelChatMessageEvent, user: Use
};
try {
await selection.execute(msg, user, {
activation
});
await selection.execute(msg, user, { activation });
}
catch (err) {
logger.err(err as string);
@@ -105,9 +103,11 @@ export async function handleCheer(msg: EventSubChannelChatMessageEvent, bits: nu
if (!selection) return;
if (await redis.sismember('disabledcheers', selection.name)) { await sendMessage(`The ${selection.name} cheer is disabled! Sorry!`, msg.messageId); return; };
if (selection.isItem && await isInvuln(user.id) && !streamerUsers.includes(user.id)) { await sendMessage(`${user.displayName} Is no longer an invuln`); await removeInvuln(user.id); };
try {
selection.execute(msg, user);
await selection.execute(msg, user);
} catch (err) {
await sendMessage(`[ERROR]: Something went wrong with cheer execution`);
logger.err(err as string);
};
};

View File

@@ -45,6 +45,7 @@ export default new Item({
}),
changeItemCount(user, userObj, ITEMNAME)
]);
await user.clearLock();
await sendMessage(`RIPBOZO ${user.displayName} exploded ${targets.length} chatter${targets.length === 1 ? '' : 's'} with their TNT RIPBOZO`);
}