(message, client)
| 153 | } |
| 154 | |
| 155 | async function handleLeveling(message, client) { |
| 156 | try { |
| 157 | const rateLimitKey = `xp-event:${message.guild.id}:${message.author.id}`; |
| 158 | const canProcess = await checkRateLimit(rateLimitKey, MESSAGE_XP_RATE_LIMIT_ATTEMPTS, MESSAGE_XP_RATE_LIMIT_WINDOW_MS); |
| 159 | if (!canProcess) { |
| 160 | return; |
| 161 | } |
| 162 | |
| 163 | const levelingConfig = await getLevelingConfig(client, message.guild.id); |
| 164 | |
| 165 | if (!levelingConfig?.enabled) { |
| 166 | return; |
| 167 | } |
| 168 | |
| 169 | if (levelingConfig.ignoredChannels?.includes(message.channel.id)) { |
| 170 | return; |
| 171 | } |
| 172 | |
| 173 | if (levelingConfig.ignoredRoles?.length > 0) { |
| 174 | const member = await message.guild.members.fetch(message.author.id).catch(() => { |
| 175 | return null; |
| 176 | }); |
| 177 | if (member && member.roles.cache.some(role => levelingConfig.ignoredRoles.includes(role.id))) { |
| 178 | return; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | if (levelingConfig.blacklistedUsers?.includes(message.author.id)) { |
| 183 | return; |
| 184 | } |
| 185 | |
| 186 | if (!message.content || message.content.trim().length === 0) { |
| 187 | return; |
| 188 | } |
| 189 | |
| 190 | const userData = await getUserLevelData(client, message.guild.id, message.author.id); |
| 191 | |
| 192 | const cooldownTime = levelingConfig.xpCooldown || 60; |
| 193 | const now = Date.now(); |
| 194 | const timeSinceLastMessage = now - (userData.lastMessage || 0); |
| 195 | |
| 196 | if (timeSinceLastMessage < cooldownTime * 1000) { |
| 197 | return; |
| 198 | } |
| 199 | |
| 200 | const minXP = levelingConfig.xpRange?.min || levelingConfig.xpPerMessage?.min || 15; |
| 201 | const maxXP = levelingConfig.xpRange?.max || levelingConfig.xpPerMessage?.max || 25; |
| 202 | |
| 203 | const safeMinXP = Math.max(1, minXP); |
| 204 | const safeMaxXP = Math.max(safeMinXP, maxXP); |
| 205 | |
| 206 | const xpToGive = Math.floor(Math.random() * (safeMaxXP - safeMinXP + 1)) + safeMinXP; |
| 207 | |
| 208 | let finalXP = xpToGive; |
| 209 | if (levelingConfig.xpMultiplier && levelingConfig.xpMultiplier > 1) { |
| 210 | finalXP = Math.floor(finalXP * levelingConfig.xpMultiplier); |
| 211 | } |
| 212 |
no test coverage detected