All checks were successful
Build and Push Docker Image / build (push) Successful in 48s
discord.js was outdated and it was making the client token reset every time i set a pfp, so this was taking forever to figure out because i dont understand packages
97 lines
3.4 KiB
JavaScript
97 lines
3.4 KiB
JavaScript
// this entire file is Opus 4.6 sorry
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.webp'];
|
|
const DEFAULT_INTERVAL = '24h';
|
|
const DEFAULT_DIR = './avatars';
|
|
|
|
/** Parse an interval string like "24h" or "30m" into milliseconds */
|
|
function parseInterval(str) {
|
|
const match = String(str).match(/^(\d+)\s*(h|m)$/i);
|
|
if (!match) {
|
|
console.warn(`Avatars: Invalid interval "${str}", falling back to ${DEFAULT_INTERVAL}`);
|
|
return parseInterval(DEFAULT_INTERVAL);
|
|
}
|
|
const value = parseInt(match[1], 10);
|
|
const unit = match[2].toLowerCase();
|
|
return unit === 'h' ? value * 60 * 60 * 1000 : value * 60 * 1000;
|
|
}
|
|
|
|
/** Scan the directory and return an array of image file paths */
|
|
function scanAvatars(dir) {
|
|
try {
|
|
return fs.readdirSync(dir)
|
|
.filter(f => IMAGE_EXTENSIONS.includes(path.extname(f).toLowerCase()))
|
|
.map(f => path.join(dir, f));
|
|
} catch (err) {
|
|
console.warn(`Avatars: Could not read directory "${dir}": ${err.message}`);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/** Pick a random avatar and set it on the client */
|
|
async function setRandomAvatar(client, avatars) {
|
|
if (!avatars.length) {
|
|
console.warn('Avatars: No images found, skipping avatar change');
|
|
return;
|
|
}
|
|
const pick = avatars[Math.floor(Math.random() * avatars.length)];
|
|
try {
|
|
await client.user.setAvatar(pick);
|
|
console.log(`Avatars: Changed to ${path.basename(pick)}`);
|
|
} catch (err) {
|
|
console.error(`Avatars: Failed to set avatar: ${err.message}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Start the avatar rotation system.
|
|
* @param {import('discord.js').Client} client - The Discord client (must be ready)
|
|
* @param {object} config - Bot config object
|
|
*/
|
|
function start(client, config = {}) {
|
|
const avatarDir = path.resolve(config.avatarDir || DEFAULT_DIR);
|
|
const intervalMs = parseInterval(config.avatarInterval || DEFAULT_INTERVAL);
|
|
|
|
// ensure the directory exists
|
|
if (!fs.existsSync(avatarDir)) {
|
|
console.warn(`Avatars: Directory "${avatarDir}" does not exist, avatar rotation disabled`);
|
|
return;
|
|
}
|
|
|
|
let avatars = scanAvatars(avatarDir);
|
|
console.log(`Avatars: Found ${avatars.length} image(s) in ${avatarDir}`);
|
|
console.log(`Avatars: Rotation interval set to ${config.avatarInterval || DEFAULT_INTERVAL}`);
|
|
|
|
// set one immediately on boot
|
|
setRandomAvatar(client, avatars);
|
|
|
|
// rotate on the configured interval
|
|
setInterval(() => {
|
|
avatars = scanAvatars(avatarDir); // re-scan in case watcher missed something
|
|
setRandomAvatar(client, avatars);
|
|
}, intervalMs);
|
|
|
|
// live-watch the folder for changes
|
|
let debounceTimer = null;
|
|
try {
|
|
fs.watch(avatarDir, (eventType, filename) => {
|
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
debounceTimer = setTimeout(() => {
|
|
const updated = scanAvatars(avatarDir);
|
|
if (updated.length !== avatars.length) {
|
|
console.log(`Avatars: Folder changed, now ${updated.length} image(s)`);
|
|
}
|
|
avatars = updated;
|
|
}, 500); // 500ms debounce
|
|
});
|
|
console.log(`Avatars: Watching "${avatarDir}" for changes`);
|
|
} catch (err) {
|
|
console.warn(`Avatars: Could not watch directory: ${err.message}`);
|
|
}
|
|
}
|
|
|
|
module.exports = { start };
|