aboutsummaryrefslogtreecommitdiff
path: root/src/listeners/message/level.ts
blob: a445d1eb6907b457290548750c2c62e90d534a16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { BotListener, CommandHandlerEvent, Emitter, Level, TanzaniteEvent, type BotCommandHandlerEvents } from '#lib';
import { MessageType } from 'discord.js';

export default class LevelListener extends BotListener {
	#levelCooldowns: Set<string> = new Set();
	public constructor() {
		super('level', {
			emitter: Emitter.CommandHandler,
			// Using messageInvalid here so commands don't give xp
			event: CommandHandlerEvent.MessageInvalid
		});
	}

	public async exec(...[message]: BotCommandHandlerEvents[CommandHandlerEvent.MessageInvalid]) {
		if (message.author.bot || !message.author || !message.inGuild()) return;
		if (!(await message.guild.hasFeature('leveling'))) return;
		if (this.#levelCooldowns.has(`${message.guildId}-${message.author.id}`)) return;

		if ((await message.guild.getSetting('noXpChannels')).includes(message.channel.id)) return;
		if (message.type !== MessageType.Default && message.type !== MessageType.Reply) return; //checks for join messages, slash commands, booster messages etc
		const [user] = await Level.findOrBuild({
			where: {
				user: message.author.id,
				guild: message.guildId
			},
			defaults: {
				user: message.author.id,
				guild: message.guildId,
				xp: 0
			}
		});
		const previousLevel = Level.convertXpToLevel(user.xp);
		const xpToGive = Level.genRandomizedXp();
		user.xp = user.xp + xpToGive;
		const success = await user.save().catch((e) => {
			void this.client.utils.handleError('level', e);
			return false;
		});
		const newLevel = Level.convertXpToLevel(user.xp);
		if (previousLevel !== newLevel)
			this.client.emit(TanzaniteEvent.LevelUpdate, message.member!, previousLevel, newLevel, user.xp, message);
		if (success)
			void this.client.logger.verbose(`level`, `Gave <<${xpToGive}>> XP to <<${message.author.tag}>> in <<${message.guild}>>.`);
		this.#levelCooldowns.add(`${message.guildId}-${message.author.id}`);
		setTimeout(() => this.#levelCooldowns.delete(`${message.guildId}-${message.author.id}`), 60_000);
	}
}