mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-18 21:11:39 +01:00
rework aniv timeouts, fix ghost whisper message, invuln status tweaks
This commit is contained in:
@@ -15,11 +15,12 @@ Admins have the power to destroy the item economy. Be very careful with admin po
|
||||
### Invulns
|
||||
|
||||
Invulns, or invulnerable chatters cannot be shot with items and cannot get hit by explosives.
|
||||
They can however use items.
|
||||
When an invuln uses an item or a lootbox they lose their invuln status.
|
||||
The intended use for invulns is for when you need to talk to a chatter, or for using other bots.
|
||||
Invulns don't need moderator or vip status in the channel.
|
||||
The chatterbot and streamer always are invuln and cannot be stripped of this status.
|
||||
Admins can add and remove invulns.
|
||||
Moderators can add and remove invulns.
|
||||
On your first message in chat you will recieve 10 minutes of invuln status.
|
||||
|
||||
### Commands
|
||||
|
||||
@@ -40,7 +41,7 @@ A full list of Commands can be found [here](#commands-1)
|
||||
### Timeouts and ghost whispers
|
||||
|
||||
If you've been timed out, you can ghost whisper a message to the chatterbot and it will relay your message to the chat.
|
||||
You can only send one message every 10 minutes.
|
||||
You can only send one message every 5 minutes.
|
||||
Try to bargain for your release with the chatter that shot you, or just call them names.
|
||||
|
||||
### Leaderboards
|
||||
|
||||
@@ -4,6 +4,8 @@ import { getUserRecord, updateUserRecord } from "db/dbUser";
|
||||
import items from "items";
|
||||
import { buildTimeString } from "lib/dateManager";
|
||||
import { timeout } from "lib/timeout";
|
||||
import { isInvuln, removeInvuln } from "lib/invuln";
|
||||
import { streamerUsers } from "main";
|
||||
|
||||
const COOLDOWN = 10 * 60 * 1000; // 10 mins (ms)
|
||||
|
||||
@@ -13,6 +15,7 @@ export default new Command({
|
||||
usertype: 'chatter',
|
||||
execution: async (msg, user) => {
|
||||
if (!await redis.exists('streamIsLive')) { await sendMessage(`No loot while stream is offline`, msg.messageId); return; };
|
||||
if (await isInvuln(msg.chatterId) && !streamerUsers.includes(msg.chatterId)) { await sendMessage(`You're no longer an invuln because used a lootbox.`, msg.messageId); await removeInvuln(msg.chatterId); };
|
||||
if (await user.itemLock()) { await sendMessage(`Cannot get loot (itemlock)`, msg.messageId); return; };
|
||||
const userData = await getUserRecord(user);
|
||||
const lastlootbox = Date.parse(userData.lastlootbox);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { redis } from "bun";
|
||||
import { Command, sendMessage } from "commands";
|
||||
import items from "items";
|
||||
import { isInvuln, removeInvuln } from "lib/invuln";
|
||||
import { streamerUsers } from "main";
|
||||
|
||||
export default new Command({
|
||||
name: 'use',
|
||||
@@ -13,6 +15,7 @@ export default new Command({
|
||||
const selection = items.get(messagequery[0].toLowerCase());
|
||||
if (!selection) { await sendMessage(`'${messagequery[0]}' is not an item`, msg.messageId); return; };
|
||||
if (await redis.sismember('disabledcommands', selection.name)) { await sendMessage(`The ${selection.prettyName} item is disabled`, msg.messageId); return; };
|
||||
if (await isInvuln(msg.chatterId) && !streamerUsers.includes(msg.chatterId)) { await sendMessage(`You're no longer an invuln because you used an item.`, msg.messageId); await removeInvuln(msg.chatterId); };
|
||||
await selection.execute(msg, user);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,10 +7,11 @@ import { isAdmin } from "lib/admins";
|
||||
import cheers from "cheers";
|
||||
import logger from "lib/logger";
|
||||
import { addMessageToChatWidget } from "web/chatWidget/message";
|
||||
import { isInvuln, setTemporaryInvuln } from "lib/invuln";
|
||||
import { isInvuln, removeInvuln, setTemporaryInvuln } from "lib/invuln";
|
||||
import { getUserRecord } from "db/dbUser";
|
||||
import { createCheerRecord } from "db/dbCheers";
|
||||
import handleAnivMessage from "lib/handleAnivMessage";
|
||||
import { Item } from "items";
|
||||
|
||||
eventSub.onChannelChatMessage(streamerId, streamerId, parseChatMessage);
|
||||
|
||||
@@ -50,8 +51,9 @@ async function handleChatMessage(msg: EventSubChannelChatMessageEvent, user: Use
|
||||
// Parse commands:
|
||||
const selected = selectCommand(msg.messageText);
|
||||
if (!selected) return;
|
||||
const { cmd: selection, activation } = selected;
|
||||
const { cmd: selection, activation, isitem } = selected;
|
||||
if (await redis.sismember('disabledcommands', selection.name)) return;
|
||||
if (isitem && await isInvuln(msg.chatterId) && !streamerUsers.includes(msg.chatterId)) { await sendMessage(`You're no longer an invuln because you used an item.`, msg.messageId); await removeInvuln(msg.chatterId); };
|
||||
|
||||
switch (selection.usertype) {
|
||||
case "admin":
|
||||
@@ -80,15 +82,16 @@ async function handleChatMessage(msg: EventSubChannelChatMessageEvent, user: Use
|
||||
type selectedCommand = {
|
||||
cmd: Command;
|
||||
activation: string;
|
||||
isitem: boolean;
|
||||
};
|
||||
|
||||
function selectCommand(message: string): selectedCommand | false {
|
||||
const specialcmdselector = message.trim().toLowerCase().split(' ')[0]!;
|
||||
const specialcmd = specialAliasCommands.get(specialcmdselector);
|
||||
if (specialcmd) return { cmd: specialcmd, activation: specialcmdselector };
|
||||
if (specialcmd) return { cmd: specialcmd, activation: specialcmdselector, isitem: specialcmd instanceof Item };
|
||||
const commandSelector = message.slice(commandPrefix.length).trim().toLowerCase().split(' ')[0]!;
|
||||
const normalcmd = commands.get(commandSelector);
|
||||
if (normalcmd) return { cmd: normalcmd, activation: commandPrefix + commandSelector };
|
||||
if (normalcmd) return { cmd: normalcmd, activation: commandPrefix + commandSelector, isitem: normalcmd instanceof Item };
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@ chatterEventSub.onUserWhisperMessage(chatterId, async msg => {
|
||||
if (await redis.ttl(`user:${msg.senderUserId}:timeout`) < 0) return;
|
||||
const cooldown = await redis.expiretime(`user:${msg.senderUserId}:whispercooldown`);
|
||||
if (cooldown < 0) {
|
||||
if (msg.messageText.length > 200) { await chatterApi.whispers.sendWhisper(chatterId, msg.senderUserId, `Message too long. Please send a shorter one.`); return; };
|
||||
await redis.set(`user:${msg.senderUserId}:whispercooldown`, '1');
|
||||
await redis.expire(`user:${msg.senderUserId}:whispercooldown`, WHISPERCOOLDOWN);
|
||||
await sendMessage(`The ghost of ${msg.senderUserDisplayName} whispered: ${msg.messageText}`);
|
||||
await chatterApi.whispers.sendWhisper(chatterId, msg.senderUserId, "Message sent. You can send another ghost whisper in 10 minutes.");
|
||||
await chatterApi.whispers.sendWhisper(chatterId, msg.senderUserId, `Message sent. You can send another ghost whisper in ${Math.floor(WHISPERCOOLDOWN / 60)} minutes.`);
|
||||
} else {
|
||||
await chatterApi.whispers.sendWhisper(chatterId, msg.senderUserId, `Wait another ${buildTimeString(cooldown * 1000, Date.now())} before sending another ghost whisper.`);
|
||||
};
|
||||
|
||||
@@ -30,7 +30,6 @@ export default new Item({
|
||||
await user.setLock();
|
||||
await Promise.all([
|
||||
timeout(target!, `You got hit by ${user.displayName}'s grenade!`, 60),
|
||||
redis.del(selection),
|
||||
sendMessage(`wybuh ${target?.displayName} got hit by ${user.displayName}'s grenade wybuh`),
|
||||
changeItemCount(user, userObj, ITEMNAME),
|
||||
createTimeoutRecord(user, target!, ITEMNAME),
|
||||
|
||||
@@ -31,7 +31,6 @@ export default new Item({
|
||||
await getUserRecord(target!); // make sure the user record exist in the database
|
||||
await Promise.all([
|
||||
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),
|
||||
]);
|
||||
|
||||
@@ -5,15 +5,45 @@ import { timeout } from "lib/timeout";
|
||||
import { sendMessage } from "commands";
|
||||
import { createAnivTimeoutRecord } from "db/dbAnivTimeouts";
|
||||
|
||||
const ANIVNAMES = ['a_n_e_e_v', 'a_n_i_v', 'a_c_a_c'];
|
||||
const ANIVNAMES = ['a_n_e_e_v', 'a_n_i_v'];
|
||||
|
||||
type anivMessageStore = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
type IsAnivMessage = {
|
||||
isAnivMessage: true;
|
||||
message: string;
|
||||
anivbot: string;
|
||||
};
|
||||
|
||||
type isNotAnivMessage = {
|
||||
isAnivMessage: false;
|
||||
};
|
||||
|
||||
type anivMessageResult = IsAnivMessage | isNotAnivMessage;
|
||||
|
||||
async function isAnivMessage(message: string): Promise<anivMessageResult> {
|
||||
const data: anivMessageStore = await redis.get('anivmessages').then(a => a === null ? {} : JSON.parse(a));
|
||||
for (const clanker of ANIVNAMES) {
|
||||
const anivmessage = data[clanker];
|
||||
if (!anivmessage) continue;
|
||||
if (anivmessage === message) return { isAnivMessage: true, message, anivbot: clanker };
|
||||
};
|
||||
return { isAnivMessage: false };
|
||||
};
|
||||
|
||||
export default async function handleMessage(msg: EventSubChannelChatMessageEvent, user: User) {
|
||||
if (ANIVNAMES.includes(user.displayName)) {
|
||||
await redis.set('lastanivmessage', msg.messageText);
|
||||
await redis.expire('lastanivmessage', 120); // store for 2 minutes
|
||||
} else if (msg.messageText === await redis.get('lastanivmessage')) await Promise.all([
|
||||
timeout(user, 'copied an aniv message', 30),
|
||||
sendMessage(`${user.displayName} got timed out for copying an a_n_e_e_v message`),
|
||||
createAnivTimeoutRecord(msg.messageText, user, 30)
|
||||
]);
|
||||
const data: anivMessageStore = await redis.get('anivmessages').then(a => a === null ? {} : JSON.parse(a));
|
||||
data[user.displayName] = msg.messageText;
|
||||
await redis.set('anivmessages', JSON.stringify(data));
|
||||
} else {
|
||||
const data = await isAnivMessage(msg.messageText);
|
||||
if (data.isAnivMessage) await Promise.all([
|
||||
timeout(user, 'copied an aniv message', 30),
|
||||
sendMessage(`${user.displayName} got timed out for copying an ${data.anivbot} message`),
|
||||
createAnivTimeoutRecord(msg.messageText, user, 30)
|
||||
]);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { redis } from "bun";
|
||||
import { streamerUsers } from "main";
|
||||
|
||||
export async function getInvulns() {
|
||||
const data = await redis.keys('user:*:invulnerable');
|
||||
@@ -13,6 +14,7 @@ export async function addInvuln(userid: string) {
|
||||
return await redis.set(`user:${userid}:invulnerable`, '1');
|
||||
};
|
||||
export async function removeInvuln(userid: string) {
|
||||
if (streamerUsers.includes(userid)) return;
|
||||
return await redis.del(`user:${userid}:invulnerable`);
|
||||
};
|
||||
export async function setTemporaryInvuln(userid: string, duration = 600) {
|
||||
|
||||
Reference in New Issue
Block a user