147 lines
5.1 KiB
JavaScript
147 lines
5.1 KiB
JavaScript
// Example of another module using scorekeeper
|
|
export const init = async (client, config) => {
|
|
// Set up message listener that adds input points when users chat
|
|
client.on('messageCreate', async (message) => {
|
|
if (message.author.bot) return;
|
|
|
|
// Skip if not in a guild
|
|
if (!message.guild) return;
|
|
|
|
// Add input points based on message length
|
|
const points = Math.min(Math.ceil(message.content.length / 10), 5);
|
|
try {
|
|
await client.scorekeeper.addInput(message.guild.id, message.author.id, points);
|
|
} catch (error) {
|
|
client.logger.error(`Error adding input points: ${error.message}`);
|
|
}
|
|
});
|
|
|
|
// Initialize voice tracking state
|
|
client.voiceTracker = {
|
|
joinTimes: new Map(), // Tracks when users joined voice
|
|
activeUsers: new Map() // Tracks users currently earning points
|
|
};
|
|
|
|
// Set up a voice state listener that adds input for voice activity
|
|
client.on('voiceStateUpdate', async (oldState, newState) => {
|
|
// Skip if not in a guild
|
|
if (!oldState.guild && !newState.guild) return;
|
|
|
|
const guild = oldState.guild || newState.guild;
|
|
const member = oldState.member || newState.member;
|
|
|
|
// User joined a voice channel
|
|
if (!oldState.channelId && newState.channelId) {
|
|
// Check if the channel has other non-bot users
|
|
const channel = newState.channel;
|
|
const otherUsers = channel.members.filter(m =>
|
|
m.id !== member.id && !m.user.bot
|
|
);
|
|
|
|
// Store join time if there's at least one other non-bot user
|
|
if (otherUsers.size > 0) {
|
|
client.voiceTracker.joinTimes.set(member.id, Date.now());
|
|
client.voiceTracker.activeUsers.set(member.id, newState.channelId);
|
|
client.logger.debug(`${member.user.tag} joined voice with others - tracking time`);
|
|
} else {
|
|
client.logger.debug(`${member.user.tag} joined voice alone or with bots - not tracking time`);
|
|
}
|
|
}
|
|
// User left a voice channel
|
|
else if (oldState.channelId && !newState.channelId) {
|
|
processVoiceLeave(client, guild, member, oldState.channelId);
|
|
}
|
|
// User switched voice channels
|
|
else if (oldState.channelId && newState.channelId && oldState.channelId !== newState.channelId) {
|
|
// Process leaving the old channel
|
|
processVoiceLeave(client, guild, member, oldState.channelId);
|
|
|
|
// Check if the new channel has other non-bot users
|
|
const channel = newState.channel;
|
|
const otherUsers = channel.members.filter(m =>
|
|
m.id !== member.id && !m.user.bot
|
|
);
|
|
|
|
// Start tracking in the new channel if there are other non-bot users
|
|
if (otherUsers.size > 0) {
|
|
client.voiceTracker.joinTimes.set(member.id, Date.now());
|
|
client.voiceTracker.activeUsers.set(member.id, newState.channelId);
|
|
}
|
|
}
|
|
|
|
// If someone joined or left a channel, update tracking for everyone in that channel
|
|
updateChannelUserTracking(client, oldState, newState);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Process when a user leaves a voice channel
|
|
*/
|
|
function processVoiceLeave(client, guild, member, channelId) {
|
|
if (client.voiceTracker.activeUsers.get(member.id) === channelId) {
|
|
const joinTime = client.voiceTracker.joinTimes.get(member.id);
|
|
|
|
if (joinTime) {
|
|
const duration = (Date.now() - joinTime) / 1000 / 60; // Duration in minutes
|
|
|
|
// Award 1 point per minute, up to 30 per session
|
|
const points = Math.min(Math.floor(duration), 30);
|
|
if (points > 0) {
|
|
try {
|
|
client.scorekeeper.addInput(guild.id, member.id, points)
|
|
.then(() => {
|
|
client.logger.debug(`Added ${points} voice activity points for ${member.user.tag}`);
|
|
})
|
|
.catch(error => {
|
|
client.logger.error(`Error adding voice points: ${error.message}`);
|
|
});
|
|
} catch (error) {
|
|
client.logger.error(`Error adding voice points: ${error.message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
client.voiceTracker.joinTimes.delete(member.id);
|
|
client.voiceTracker.activeUsers.delete(member.id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates tracking for all users in affected channels
|
|
*/
|
|
function updateChannelUserTracking(client, oldState, newState) {
|
|
// Get the affected channels
|
|
const affectedChannels = new Set();
|
|
if (oldState.channelId) affectedChannels.add(oldState.channelId);
|
|
if (newState.channelId) affectedChannels.add(newState.channelId);
|
|
|
|
for (const channelId of affectedChannels) {
|
|
const channel = oldState.guild.channels.cache.get(channelId);
|
|
if (!channel) continue;
|
|
|
|
// Check if the channel has at least 2 non-bot users
|
|
const nonBotMembers = channel.members.filter(m => !m.user.bot);
|
|
const hasMultipleUsers = nonBotMembers.size >= 2;
|
|
|
|
// For each user in the channel
|
|
channel.members.forEach(channelMember => {
|
|
if (channelMember.user.bot) return; // Skip bots
|
|
|
|
const userId = channelMember.id;
|
|
const isActive = client.voiceTracker.activeUsers.get(userId) === channelId;
|
|
|
|
// Should be active but isn't yet
|
|
if (hasMultipleUsers && !isActive) {
|
|
client.voiceTracker.joinTimes.set(userId, Date.now());
|
|
client.voiceTracker.activeUsers.set(userId, channelId);
|
|
client.logger.debug(`Starting tracking for ${channelMember.user.tag} in ${channel.name}`);
|
|
}
|
|
// Should not be active but is
|
|
else if (!hasMultipleUsers && isActive) {
|
|
processVoiceLeave(client, oldState.guild, channelMember, channelId);
|
|
client.logger.debug(`Stopping tracking for ${channelMember.user.tag} - not enough users`);
|
|
}
|
|
});
|
|
}
|
|
}
|