Added Counting Feature

This commit is contained in:
Ahmad 2025-03-02 05:47:53 -05:00
parent de599534f0
commit 95143d8c93
No known key found for this signature in database
GPG key ID: 8FD8A93530D182BF
7 changed files with 343 additions and 3 deletions

157
src/util/countingManager.ts Normal file
View file

@ -0,0 +1,157 @@
import { Message } from 'discord.js';
import { getJson, setJson } from '../db/redis.js';
interface CountingData {
currentCount: number;
lastUserId: string | null;
highestCount: number;
totalCorrect: number;
}
const MILESTONE_REACTIONS = {
normal: '✅',
multiples25: '✨',
multiples50: '⭐',
multiples100: '🎉',
};
export async function initializeCountingData(): Promise<CountingData> {
const exists = await getJson<CountingData>('counting');
if (exists) return exists;
const initialData: CountingData = {
currentCount: 0,
lastUserId: null,
highestCount: 0,
totalCorrect: 0,
};
await setJson<CountingData>('counting', initialData);
return initialData;
}
export async function getCountingData(): Promise<CountingData> {
const data = await getJson<CountingData>('counting');
if (!data) {
return initializeCountingData();
}
return data;
}
export async function updateCountingData(
data: Partial<CountingData>,
): Promise<void> {
const currentData = await getCountingData();
const updatedData = { ...currentData, ...data };
await setJson<CountingData>('counting', updatedData);
}
export async function resetCounting(): Promise<void> {
await updateCountingData({
currentCount: 0,
lastUserId: null,
});
return;
}
export async function processCountingMessage(message: Message): Promise<{
isValid: boolean;
expectedCount?: number;
isMilestone?: boolean;
milestoneType?: keyof typeof MILESTONE_REACTIONS;
reason?: string;
}> {
try {
const countingData = await getCountingData();
const content = message.content.trim();
const count = Number(content);
if (isNaN(count) || !Number.isInteger(count)) {
return {
isValid: false,
expectedCount: countingData.currentCount + 1,
reason: 'not_a_number',
};
}
const expectedCount = countingData.currentCount + 1;
if (count !== expectedCount) {
return {
isValid: false,
expectedCount,
reason: count > expectedCount ? 'too_high' : 'too_low',
};
}
if (countingData.lastUserId === message.author.id) {
return { isValid: false, expectedCount, reason: 'same_user' };
}
const newCount = countingData.currentCount + 1;
const newHighestCount = Math.max(newCount, countingData.highestCount);
await updateCountingData({
currentCount: newCount,
lastUserId: message.author.id,
highestCount: newHighestCount,
totalCorrect: countingData.totalCorrect + 1,
});
let isMilestone = false;
let milestoneType: keyof typeof MILESTONE_REACTIONS = 'normal';
if (newCount % 100 === 0) {
isMilestone = true;
milestoneType = 'multiples100';
} else if (newCount % 50 === 0) {
isMilestone = true;
milestoneType = 'multiples50';
} else if (newCount % 25 === 0) {
isMilestone = true;
milestoneType = 'multiples25';
}
return {
isValid: true,
expectedCount: newCount + 1,
isMilestone,
milestoneType,
};
} catch (error) {
console.error('Error processing counting message:', error);
return { isValid: false, reason: 'error' };
}
}
export async function addCountingReactions(
message: Message,
milestoneType: keyof typeof MILESTONE_REACTIONS,
): Promise<void> {
try {
await message.react(MILESTONE_REACTIONS[milestoneType]);
if (milestoneType === 'multiples100') {
await message.react('💯');
}
} catch (error) {
console.error('Error adding counting reactions:', error);
}
}
export async function getCountingStatus(): Promise<string> {
const data = await getCountingData();
return `Current count: ${data.currentCount}\nHighest count ever: ${data.highestCount}\nTotal correct counts: ${data.totalCorrect}`;
}
export async function setCount(count: number): Promise<void> {
if (!Number.isInteger(count) || count < 0) {
throw new Error('Count must be a non-negative integer.');
}
await updateCountingData({
currentCount: count,
lastUserId: null,
});
}