113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
|
import { ActivityType, Client } from 'discord.js';
|
||
|
import { config } from '../config/config';
|
||
|
import { getRandomElement } from './random';
|
||
|
import { getAvailableThemeIds, getTheme } from './themes';
|
||
|
|
||
|
export class StatusManager {
|
||
|
private client: Client;
|
||
|
private statusUpdateInterval: NodeJS.Timeout | null = null;
|
||
|
|
||
|
constructor(client: Client) {
|
||
|
this.client = client;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Start rotating status messages
|
||
|
*/
|
||
|
public startStatusRotation(): void {
|
||
|
// Clear any existing interval
|
||
|
if (this.statusUpdateInterval) {
|
||
|
clearInterval(this.statusUpdateInterval);
|
||
|
}
|
||
|
|
||
|
// Update status immediately
|
||
|
this.updateStatus();
|
||
|
|
||
|
// Set interval for future updates
|
||
|
this.statusUpdateInterval = setInterval(() => {
|
||
|
this.updateStatus();
|
||
|
}, config.statusUpdateInterval * 1000);
|
||
|
|
||
|
console.log(`Status rotation enabled, updating every ${config.statusUpdateInterval} seconds`);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Stop rotating status messages
|
||
|
*/
|
||
|
public stopStatusRotation(): void {
|
||
|
if (this.statusUpdateInterval) {
|
||
|
clearInterval(this.statusUpdateInterval);
|
||
|
this.statusUpdateInterval = null;
|
||
|
console.log('Status rotation disabled');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if the bot is currently in any voice channel
|
||
|
*/
|
||
|
private isInVoiceChannel(): boolean {
|
||
|
if (!this.client.guilds) return false;
|
||
|
|
||
|
// Check if the bot is in a voice channel in any guild
|
||
|
for (const guild of this.client.guilds.cache.values()) {
|
||
|
const member = guild.members.cache.get(this.client.user?.id || '');
|
||
|
if (member?.voice.channel) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the bot's status message
|
||
|
*/
|
||
|
private updateStatus(): void {
|
||
|
if (!this.client.user) return;
|
||
|
|
||
|
// Get guild count
|
||
|
const guildCount = this.client.guilds.cache.size;
|
||
|
|
||
|
// Check if the bot is in a voice channel
|
||
|
const inVoiceChannel = this.isInVoiceChannel();
|
||
|
|
||
|
// Randomly select a theme
|
||
|
const themeIds = getAvailableThemeIds();
|
||
|
const randomThemeId = getRandomElement(themeIds);
|
||
|
const theme = getTheme(randomThemeId);
|
||
|
|
||
|
// Get a random status message based on voice channel status
|
||
|
const statusList = inVoiceChannel ? theme.statusMessages.inVoice : theme.statusMessages.normal;
|
||
|
let statusMessage = getRandomElement(statusList);
|
||
|
|
||
|
// Replace guild count placeholder
|
||
|
statusMessage = statusMessage.replace('GUILD_COUNT', guildCount.toString());
|
||
|
|
||
|
// Add the theme emoji to the status
|
||
|
statusMessage = `${theme.emojiIcon} ${statusMessage}`;
|
||
|
|
||
|
// Choose a random activity type
|
||
|
const activityTypes = [
|
||
|
ActivityType.Playing,
|
||
|
ActivityType.Watching,
|
||
|
ActivityType.Listening,
|
||
|
ActivityType.Competing
|
||
|
];
|
||
|
const activityType = getRandomElement(activityTypes);
|
||
|
|
||
|
// Set the new activity
|
||
|
this.client.user.setActivity(statusMessage, { type: activityType });
|
||
|
console.log(`Status updated (${inVoiceChannel ? 'in voice' : 'normal'}): ${ActivityType[activityType]} ${statusMessage}`);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set a specific status
|
||
|
*/
|
||
|
public setStatus(message: string, type: ActivityType = ActivityType.Playing): void {
|
||
|
if (!this.client.user) return;
|
||
|
|
||
|
this.client.user.setActivity(message, { type });
|
||
|
console.log(`Status set: ${ActivityType[type]} ${message}`);
|
||
|
}
|
||
|
}
|