sxcybot

Discord bot for OSRS based channels
git clone git://git.wimdupont.com/sxcybot.git
Log | Files | Refs | README | LICENSE

commit 37d6ce1d4b7d5bed254ae29fb9c5d3da71f61fb5
parent 61664cd8cdcb998cda58ad7b5680c10e95306c7e
Author: Wim Dupont <wim@wimdupont.com>
Date:   Sun, 26 Feb 2023 10:46:44 +0100

added pvm monitor and fix db init

Diffstat:
Mpom.xml | 2+-
Msrc/main/java/com/sxcy/sxcybot/SxcyBotApplication.java | 5++++-
Msrc/main/java/com/sxcy/sxcybot/enums/Command.java | 3++-
Msrc/main/java/com/sxcy/sxcybot/listeners/CommandListener.java | 4++++
Msrc/main/java/com/sxcy/sxcybot/listeners/member/PvmRoleCheckListener.java | 6+++---
Asrc/main/java/com/sxcy/sxcybot/listeners/member/PvmRolePollListener.java | 30++++++++++++++++++++++++++++++
Msrc/main/java/com/sxcy/sxcybot/repository/guild/pvmrole/dao/PvmKcSnapshot.java | 6++++--
Msrc/main/java/com/sxcy/sxcybot/services/OsrsMonitoringService.java | 38+++++++++++++++++++++++++++++++-------
Msrc/main/java/com/sxcy/sxcybot/services/PvMRoleResolver.java | 6+-----
Msrc/main/java/com/sxcy/sxcybot/services/guild/ChannelDetailService.java | 4++++
Msrc/main/java/com/sxcy/sxcybot/services/guild/impl/ChannelDetailServiceImpl.java | 7+++++++
Asrc/main/resources/db/migration/V1_10__db-add_missing_from_init.sql | 3+++
Msrc/main/resources/releasenotes.csv | 3++-
13 files changed, 96 insertions(+), 21 deletions(-)

diff --git a/pom.xml b/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>3.0.1</version> + <version>3.0.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.sxcy</groupId> diff --git a/src/main/java/com/sxcy/sxcybot/SxcyBotApplication.java b/src/main/java/com/sxcy/sxcybot/SxcyBotApplication.java @@ -7,6 +7,7 @@ import com.sxcy.sxcybot.listeners.EventWaiterUtil; import com.sxcy.sxcybot.listeners.GuildMemberEventListener; import com.sxcy.sxcybot.listeners.PollReactionListener; import com.sxcy.sxcybot.services.PvMRoleResolver; +import com.sxcy.sxcybot.services.guild.ChannelDetailService; import com.sxcy.sxcybot.util.Constants.Commands; import com.sxcy.sxcybot.util.ReleaseNotesUtil; import lombok.extern.slf4j.Slf4j; @@ -44,6 +45,8 @@ public class SxcyBotApplication implements CommandLineRunner { @Autowired private ReleaseNotesUtil releaseNotesUtil; @Autowired + private ChannelDetailService channelDetailService; + @Autowired private PvMRoleResolver pvMRoleResolver; @SuppressWarnings("unused") @@ -71,7 +74,7 @@ public class SxcyBotApplication implements CommandLineRunner { log.debug("Awaiting jda " + jda); jda.awaitReady(); log.debug("Jda " + jda + " ready"); - pvMRoleResolver.setJda(jda); + channelDetailService.setJda(jda); processArgs(jda, args); } catch (InterruptedException e) { log.error(e.getMessage(), e); diff --git a/src/main/java/com/sxcy/sxcybot/enums/Command.java b/src/main/java/com/sxcy/sxcybot/enums/Command.java @@ -9,7 +9,8 @@ public enum Command { // EVENT("Create an event."), POLL("Start a poll with default options (Accept, Deny, Unsure), separate command by title with space."), CPOLL("Start a custom poll - choose your own poll options and reaction emoji's, separate command by title with space."), - PVMCHECK("Status update of current PvM Role competition."), + PVMPOLL("Poll current standings of the PvM Role competition."), + PVMCHECK("Check if PvM competitors can be found."), HELP("Show all commands with description."), diff --git a/src/main/java/com/sxcy/sxcybot/listeners/CommandListener.java b/src/main/java/com/sxcy/sxcybot/listeners/CommandListener.java @@ -13,6 +13,7 @@ import com.sxcy.sxcybot.listeners.member.PingListener; import com.sxcy.sxcybot.listeners.member.PollListener; import com.sxcy.sxcybot.listeners.member.PriceListener; import com.sxcy.sxcybot.listeners.member.PvmListListener; +import com.sxcy.sxcybot.listeners.member.PvmRolePollListener; import com.sxcy.sxcybot.listeners.member.PvmRoleCheckListener; import com.sxcy.sxcybot.listeners.member.RuleListener; import com.sxcy.sxcybot.listeners.member.RulesListener; @@ -63,6 +64,8 @@ public class CommandListener extends ListenerAdapter { private final HiscoreBossListener hiscoreBossListener; @NonNull private final PvmRoleCheckListener pvmRoleCheckListener; + @NonNull + private final PvmRolePollListener pvmRolePollListener; @Override public void onMessageReceived(@Nonnull MessageReceivedEvent event) { @@ -88,6 +91,7 @@ public class CommandListener extends ListenerAdapter { case KC -> killCountListener.proces(event); case PVMLIST -> pvmListListener.proces(event); case BOSSLIST -> hiscoreBossListener.proces(event); + case PVMPOLL -> pvmRolePollListener.proces(event); case PVMCHECK -> pvmRoleCheckListener.proces(event); case HELP -> helpListener.proces(event); default -> { diff --git a/src/main/java/com/sxcy/sxcybot/listeners/member/PvmRoleCheckListener.java b/src/main/java/com/sxcy/sxcybot/listeners/member/PvmRoleCheckListener.java @@ -1,7 +1,7 @@ package com.sxcy.sxcybot.listeners.member; import com.sxcy.sxcybot.listeners.Listener; -import com.sxcy.sxcybot.services.PvMRoleResolver; +import com.sxcy.sxcybot.services.OsrsMonitoringService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.PrivateChannel; @@ -14,14 +14,14 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class PvmRoleCheckListener implements Listener { - private final PvMRoleResolver pvMRoleResolver; + private final OsrsMonitoringService osrsMonitoringService; @Override public void proces(MessageReceivedEvent event) { if (event.getMember() != null) { try { PrivateChannel privateChannel = event.getMember().getUser().openPrivateChannel().complete(true); - pvMRoleResolver.resolvePvMRoles(false, privateChannel); + osrsMonitoringService.monitorPvmRoleUserHiscores(privateChannel); } catch (RateLimitedException e) { log.error(e.getMessage(), e); } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/member/PvmRolePollListener.java b/src/main/java/com/sxcy/sxcybot/listeners/member/PvmRolePollListener.java @@ -0,0 +1,30 @@ +package com.sxcy.sxcybot.listeners.member; + +import com.sxcy.sxcybot.listeners.Listener; +import com.sxcy.sxcybot.services.PvMRoleResolver; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.dv8tion.jda.api.entities.PrivateChannel; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.exceptions.RateLimitedException; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class PvmRolePollListener implements Listener { + + private final PvMRoleResolver pvMRoleResolver; + + @Override + public void proces(MessageReceivedEvent event) { + if (event.getMember() != null) { + try { + PrivateChannel privateChannel = event.getMember().getUser().openPrivateChannel().complete(true); + pvMRoleResolver.resolvePvMRoles(false, privateChannel); + } catch (RateLimitedException e) { + log.error(e.getMessage(), e); + } + } + } +} diff --git a/src/main/java/com/sxcy/sxcybot/repository/guild/pvmrole/dao/PvmKcSnapshot.java b/src/main/java/com/sxcy/sxcybot/repository/guild/pvmrole/dao/PvmKcSnapshot.java @@ -5,8 +5,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -35,7 +36,8 @@ public class PvmKcSnapshot { @GenericGenerator(name = "uuid", strategy = "uuid") private String id; - @OneToOne + @ManyToOne + @JoinColumn(name = "pvm_role_user_id") private PvmRoleUser pvmRoleUser; @OneToMany(mappedBy = "pvmKcSnapshot", cascade = CascadeType.ALL, orphanRemoval = true) diff --git a/src/main/java/com/sxcy/sxcybot/services/OsrsMonitoringService.java b/src/main/java/com/sxcy/sxcybot/services/OsrsMonitoringService.java @@ -6,12 +6,16 @@ import com.sxcy.sxcybot.model.OsrsBossKc; import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleUserService; import lombok.RequiredArgsConstructor; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.PrivateChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import java.awt.Color; +import java.util.ArrayList; import java.util.List; @Service @@ -34,25 +38,45 @@ public class OsrsMonitoringService { public void monitor() { try { monitorHiscores(); - monitorPvmRoleUserHiscores(); + monitorPvmRoleUserHiscores(null); } catch (Exception e) { logger.error(e.getMessage()); } } - public void monitorPvmRoleUserHiscores() { - int errors = 0; + public void monitorPvmRoleUserHiscores(PrivateChannel privateChannel) { + List<PvmRoleUser> unfound = new ArrayList<>(); for (PvmRoleUser pvmRoleUser : pvmRoleUserService.findAll()) { try { hiScoreClient.getHiScoreBossKc(pvmRoleUser.getRsn(), null).orElseThrow(); } catch (Exception e) { - logger.error("PvmRoleUserHiscores: no hiScores found for {}", pvmRoleUser.getRsn()); - errors++; + unfound.add(pvmRoleUser); } } - if (errors == 0) - logger.info("All pvmRoleUser hiscores have been found."); + messageUnfoundResults(unfound, privateChannel); + } + + private void messageUnfoundResults(List<PvmRoleUser> unfound, PrivateChannel privateChannel) { + if (privateChannel == null) { + if (!unfound.isEmpty()) { + logger.error("No hiScores found for: {}", unfound.stream().map(PvmRoleUser::getRsn).toList()); + } else { + logger.info("All PvM Role competitors have been found in the hiscores."); + } + } else { + EmbedBuilder embedBuilder = new EmbedBuilder(); + embedBuilder.setColor(Color.red); + embedBuilder.setTitle("PvM competitor check"); + if (!unfound.isEmpty()) { + embedBuilder.setDescription("No hiscores found for following competitors:"); + unfound.forEach(competitor -> + embedBuilder.addField(competitor.getRsn(), String.format("Discord: %s", competitor.getDiscordName()), true)); + } else { + embedBuilder.setDescription("All PvM role competitors have been found in the hiscores."); + } + privateChannel.sendMessageEmbeds(embedBuilder.build()).queue(); + } } public void monitorHiscores() throws EntityNotFoundException { diff --git a/src/main/java/com/sxcy/sxcybot/services/PvMRoleResolver.java b/src/main/java/com/sxcy/sxcybot/services/PvMRoleResolver.java @@ -10,9 +10,7 @@ import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleSnapshotComparatorService; import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleUserService; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.PrivateChannel; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -37,8 +35,6 @@ public class PvMRoleResolver { private final PvmRoleSnapshotComparatorService pvmRoleSnapshotComparatorService; @NonNull private final PvmRoleAssignerService pvmRoleAssignerService; - @Setter - private JDA jda; @Scheduled(cron = "${pvm.role.schedule}") @SuppressWarnings("unused") @@ -53,7 +49,7 @@ public class PvMRoleResolver { if (!pvmRole.equals(PvmRole.UNUSED)) scoreBoard.put(pvmRole, new LinkedHashMap<>()); } - jda.getGuilds().forEach(guild -> + channelDetailService.getJda().getGuilds().forEach(guild -> channelDetailService.findAll().stream().findAny().ifPresent(channelDetail -> (privateChannel == null ? guild.getTextChannelsByName(channelDetail.getPvmRoleChannel(), true) : List.of(privateChannel)) .forEach(textChannel -> { diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/ChannelDetailService.java b/src/main/java/com/sxcy/sxcybot/services/guild/ChannelDetailService.java @@ -1,10 +1,14 @@ package com.sxcy.sxcybot.services.guild; import com.sxcy.sxcybot.repository.guild.dao.ChannelDetail; +import net.dv8tion.jda.api.JDA; import java.util.List; public interface ChannelDetailService { List<ChannelDetail> findAll(); + + void setJda(JDA jda); + JDA getJda(); } diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/impl/ChannelDetailServiceImpl.java b/src/main/java/com/sxcy/sxcybot/services/guild/impl/ChannelDetailServiceImpl.java @@ -3,8 +3,11 @@ package com.sxcy.sxcybot.services.guild.impl; import com.sxcy.sxcybot.repository.guild.ChannelDetailRepository; import com.sxcy.sxcybot.repository.guild.dao.ChannelDetail; import com.sxcy.sxcybot.services.guild.ChannelDetailService; +import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.dv8tion.jda.api.JDA; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,6 +21,10 @@ public class ChannelDetailServiceImpl implements ChannelDetailService { @NonNull private final ChannelDetailRepository channelDetailRepository; + @Setter + @Getter + private JDA jda; + @Override public List<ChannelDetail> findAll() { return channelDetailRepository.findAll(); diff --git a/src/main/resources/db/migration/V1_10__db-add_missing_from_init.sql b/src/main/resources/db/migration/V1_10__db-add_missing_from_init.sql @@ -0,0 +1,3 @@ +ALTER TABLE pvm_user_kc ADD COLUMN IF NOT EXISTS kc INTEGER DEFAULT 0; +ALTER TABLE pvm_kc_snapshot ADD COLUMN IF NOT EXISTS pvm_role_user_id VARCHAR(36); +ALTER TABLE pvm_kc_snapshot ADD CONSTRAINT fk_pvmroleuser_snapshot FOREIGN KEY IF NOT EXISTS (pvm_role_user_id) REFERENCES pvm_role_user (id); diff --git a/src/main/resources/releasenotes.csv b/src/main/resources/releasenotes.csv @@ -1 +1,2 @@ -Added sb-pvmcheck command;This command shows the current hiscores of the PvM Role competition through DM. +Renamed sb-pvmcheck command to sb-pvmpoll;This command shows the current hiscores of the PvM Role competition through DM. +Added new sb-pvmcheck command;This command checks for competitors that cannot be found in the hiscores.