package cc.fascinated.bat.service; import cc.fascinated.bat.common.TimerUtils; import cc.fascinated.bat.event.EventListener; import cc.fascinated.bat.model.BatGuild; import cc.fascinated.bat.premium.PremiumProfile; import com.mongodb.client.model.Filters; import lombok.Getter; import lombok.NonNull; import lombok.extern.log4j.Log4j2; import net.dv8tion.jda.api.events.guild.GuildJoinEvent; import net.dv8tion.jda.api.events.guild.GuildLeaveEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.bson.Document; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @author Fascinated (fascinated7) */ @Service @Log4j2(topic = "Guild Service") @Getter @DependsOn({"discordService", "mongoService"}) public class GuildService extends ListenerAdapter implements EventListener { private static final long SAVE_INTERVAL = TimeUnit.MINUTES.toMillis(5); /** * The cached guilds */ private final Map guilds = new HashMap<>(); @Autowired public GuildService() { TimerUtils.scheduleRepeating(() -> { long before = System.currentTimeMillis(); for (BatGuild guild : guilds.values()) { guild.save(); } log.info("Saved {} guilds in {}ms", guilds.size(), System.currentTimeMillis() - before); }, SAVE_INTERVAL, SAVE_INTERVAL); DiscordService.JDA.addEventListener(this); } /** * Validates the premium status of all guilds *

* This method is scheduled to run every day at midnight *

*/ @Scheduled(cron = "0 0 0 * * *") private void validatePremiumStatus() { for (BatGuild guild : guilds.values()) { PremiumProfile premium = guild.getPremiumProfile(); if (!premium.hasExpired()) { return; } premium.removePremium(); log.info("Removed premium status from guild \"{}\"", guild.getName()); } } /** * Gets a guild by its ID * * @param id The ID of the guild * @return The guild */ public BatGuild getGuild(@NonNull String id) { long before = System.currentTimeMillis(); // Guild is cached if (guilds.containsKey(id)) { return guilds.get(id); } if (DiscordService.JDA.getGuildById(id) == null) { log.warn("Attempted to get guild with ID \"{}\" but it does not exist", id); return null; } // Guild is not cached Document document = MongoService.INSTANCE.getGuildsCollection().find(Filters.eq("_id", id)).first(); if (document != null) { BatGuild guild = new BatGuild(id, document); guilds.put(id, guild); log.info("Loaded guild \"{}\" in {}ms", guild.getName(), System.currentTimeMillis() - before); return guild; } // New guild BatGuild guild = new BatGuild(id, new Document()); guilds.put(id, guild); log.info("Created guild \"{}\" - \"{}\"", guild.getName(), guild.getId()); return guild; } @Override public final void onGuildJoin(GuildJoinEvent event) { BatGuild guild = getGuild(event.getGuild().getId()); log.info("Joined guild \"{}\"", guild.getName()); } @Override public void onGuildLeave(@NotNull GuildLeaveEvent event) { BatGuild guild = getGuild(event.getGuild().getId()); log.info("Left guild \"{}\"", guild.getName()); guild.save(); guilds.remove(guild.getId()); } @Override public void onSpringShutdown() { log.info("Saving all guilds before shutdown..."); for (BatGuild guild : guilds.values()) { guild.save(); } log.info("Saved all guilds."); } }