sxcybot

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

commit 246f657572793aa5a43097b4c1b880772f4823d8
parent ce766d042cec44879926df644ee6bffd126bb0fd
Author: WimDupont <WimDupont@users.noreply.gitlab.com>
Date:   Sat,  6 Nov 2021 20:37:30 +0100

added sb-pvmcheck command and some minor cleanup

Diffstat:
Msrc/main/java/com/sxcy/sxcybot/SxcyBotApplication.java | 12+++++++-----
Msrc/main/java/com/sxcy/sxcybot/client/GrandExchangeClient.java | 13+++++++++----
Msrc/main/java/com/sxcy/sxcybot/client/HiScoreClient.java | 29+++++++++++++++++++----------
Asrc/main/java/com/sxcy/sxcybot/config/AppConfig.java | 15+++++++++++++++
Msrc/main/java/com/sxcy/sxcybot/enums/Command.java | 1+
Msrc/main/java/com/sxcy/sxcybot/listeners/CommandListener.java | 9+++++++--
Msrc/main/java/com/sxcy/sxcybot/listeners/EventWaiterUtil.java | 7+++++--
Msrc/main/java/com/sxcy/sxcybot/listeners/GuildMemberEventListener.java | 4+++-
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/BanlistListener.java | 4+++-
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/EditBanlistListener.java | 27+++++++++++++--------------
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/EditPvmListener.java | 24++++++++++++------------
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/EditRoleListener.java | 24+++++++++++++-----------
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/EditRuleListener.java | 24++++++++++++------------
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/RoleAssignListener.java | 4+++-
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/pvmrole/AddPvmListener.java | 6+++---
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/role/DeleteRoleListener.java | 3++-
Msrc/main/java/com/sxcy/sxcybot/listeners/admin/role/UpdateRoleListener.java | 3++-
Msrc/main/java/com/sxcy/sxcybot/listeners/member/CustomPollListener.java | 7++++---
Msrc/main/java/com/sxcy/sxcybot/listeners/member/EventListener.java | 4+++-
Msrc/main/java/com/sxcy/sxcybot/listeners/member/PriceListener.java | 4++--
Asrc/main/java/com/sxcy/sxcybot/listeners/member/PvmRoleCheckListener.java | 30++++++++++++++++++++++++++++++
Msrc/main/java/com/sxcy/sxcybot/model/CombatDto.java | 1-
Msrc/main/java/com/sxcy/sxcybot/model/EditListenerDto.java | 2+-
Asrc/main/java/com/sxcy/sxcybot/services/PvMRoleResolver.java | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/main/java/com/sxcy/sxcybot/services/PvMRoleScheduler.java | 61-------------------------------------------------------------
Msrc/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleAssignerService.java | 2+-
Asrc/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleSnapshotComparatorService.java | 19+++++++++++++++++++
Dsrc/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleSnapshotComparerService.java | 17-----------------
Msrc/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleAssignerServiceImpl.java | 4++--
Asrc/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleSnapshotComparatorServiceImpl.java | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleSnapshotComparerServiceImpl.java | 93-------------------------------------------------------------------------------
Msrc/main/resources/releasenotes.csv | 2+-
32 files changed, 366 insertions(+), 263 deletions(-)

diff --git a/src/main/java/com/sxcy/sxcybot/SxcyBotApplication.java b/src/main/java/com/sxcy/sxcybot/SxcyBotApplication.java @@ -6,9 +6,10 @@ import com.sxcy.sxcybot.listeners.CommandListener; import com.sxcy.sxcybot.listeners.EventWaiterUtil; import com.sxcy.sxcybot.listeners.GuildMemberEventListener; import com.sxcy.sxcybot.listeners.PollReactionListener; -import com.sxcy.sxcybot.services.PvMRoleScheduler; +import com.sxcy.sxcybot.services.PvMRoleResolver; import com.sxcy.sxcybot.util.Constants.Commands; import com.sxcy.sxcybot.util.ReleaseNotesUtil; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Activity; @@ -24,6 +25,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; import javax.security.auth.login.LoginException; import java.util.Arrays; +@Slf4j @SpringBootApplication @EnableScheduling @ComponentScan @@ -42,7 +44,7 @@ public class SxcyBotApplication implements CommandLineRunner { @Autowired private ReleaseNotesUtil releaseNotesUtil; @Autowired - private PvMRoleScheduler pvMRoleScheduler; + private PvMRoleResolver pvMRoleResolver; @SuppressWarnings("unused") @Value("${discord.bot.token}") @@ -66,10 +68,10 @@ public class SxcyBotApplication implements CommandLineRunner { .build(); try { jda.awaitReady(); - pvMRoleScheduler.setJda(jda); + pvMRoleResolver.setJda(jda); processArgs(jda, args); } catch (InterruptedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } @@ -77,7 +79,7 @@ public class SxcyBotApplication implements CommandLineRunner { if (args.length == 0 || Arrays.stream(args).noneMatch("noNotes"::equalsIgnoreCase)) releaseNotesUtil.showReleaseNotes(jda); if (args.length > 0 && Arrays.stream(args).anyMatch("snap"::equalsIgnoreCase)) - pvMRoleScheduler.resolvePvMRoles(); + pvMRoleResolver.resolvePvMRoles(); } } diff --git a/src/main/java/com/sxcy/sxcybot/client/GrandExchangeClient.java b/src/main/java/com/sxcy/sxcybot/client/GrandExchangeClient.java @@ -4,25 +4,30 @@ import com.sxcy.sxcybot.exceptions.EntityNotFoundException; import com.sxcy.sxcybot.model.OsrsItem; import com.sxcy.sxcybot.util.NumberFormatter; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; import net.dv8tion.jda.api.entities.MessageChannel; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.util.Map; @Component +@RequiredArgsConstructor public class GrandExchangeClient { private static final String URL = "https://api.weirdgloop.org/exchange/history/osrs/latest?name=%s&lang=en"; + private final ObjectMapper objectMapper; + @SuppressWarnings("unchecked") public String getPrice(String itemName, MessageChannel channel) throws EntityNotFoundException { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new ClientErrorHandler(channel)); - ObjectMapper objectMapper = new ObjectMapper(); + RestTemplate restTemplate = new RestTemplateBuilder() + .errorHandler(new ClientErrorHandler(channel)) + .build(); Object result = restTemplate.getForEntity(String.format(URL, itemName), Object.class).getBody(); if (result != null) { try { - return NumberFormatter.format(objectMapper.convertValue(((Map<String,Object>) result).values().iterator().next(), OsrsItem.class).getPrice()); + return NumberFormatter.format(objectMapper.convertValue(((Map<String, Object>) result).values().iterator().next(), OsrsItem.class).getPrice()); } catch (IllegalArgumentException e) { throw new EntityNotFoundException(String.format("Item with name %s not found.", itemName)); } diff --git a/src/main/java/com/sxcy/sxcybot/client/HiScoreClient.java b/src/main/java/com/sxcy/sxcybot/client/HiScoreClient.java @@ -11,7 +11,9 @@ import com.sxcy.sxcybot.services.osrs.OsrsHiscoreStatService; import com.sxcy.sxcybot.util.NumberFormatter; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.MessageChannel; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @@ -21,11 +23,17 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +@Slf4j @Component @RequiredArgsConstructor public class HiScoreClient { private static final String URL = "https://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=%s"; + private static final int STATS_START = 0; + private static final int STATS_END = 22; + private static final int BOSS_START = 36; + private static final int BOSS_END = 83; + @NonNull private final OsrsHiscoreBossService osrsHiscoreBossService; @NonNull @@ -35,29 +43,30 @@ public class HiScoreClient { List<OsrsHiscoreStat> hiscoreStats = osrsHiscoreStatService.findAll(); return getHiScores(playername, channel, (osrsStat, hiScoreStatValues, i) -> OsrsStat.builder() .name(hiscoreStats.stream().filter(f -> f.getOrderValue() == i).findFirst().orElseThrow(() - -> new EntityNotFoundException("OsrsStatName for order not found!")) + -> new EntityNotFoundException("OsrsStatName for order not found!")) .getName()) .rank(NumberFormatter.format(hiScoreStatValues.get(0))) .level(hiScoreStatValues.get(1)) .experience(NumberFormatter.format(hiScoreStatValues.get(2))) - .build(), 0, 22); + .build(), STATS_START, STATS_END); } public Optional<List<OsrsBossKc>> getHiScoreBossKc(String playername, MessageChannel channel) { List<OsrsHiscoreBoss> hiscoreBosses = osrsHiscoreBossService.findAll(); return getHiScores(playername, channel, (osrsKc, hiScoreKcValues, i) -> OsrsBossKc.builder() - .name(hiscoreBosses.stream().filter(f -> f.getOrderValue() == i).findFirst().orElseThrow(() + .name(hiscoreBosses.stream().filter(f -> f.getOrderValue() == i).findFirst().orElseThrow(() -> new EntityNotFoundException("OsrsBoss for order not found!")) - .getName()) - .rank(hiScoreKcValues.get(0)) - .kc(hiScoreKcValues.get(1)).build() - , 36, 83); + .getName()) + .rank(hiScoreKcValues.get(0)) + .kc(hiScoreKcValues.get(1)) + .build(), BOSS_START, BOSS_END); } private <T> Optional<List<T>> getHiScores(String playername, MessageChannel channel, HiScoreBuilder<T> hiScoreBuilder, int fromIndex, int toIndex) { List<T> hiScoreList = new ArrayList<>(); - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new ClientErrorHandler(channel)); + RestTemplate restTemplate = new RestTemplateBuilder() + .errorHandler(new ClientErrorHandler(channel)) + .build(); String result = restTemplate.getForObject(String.format(URL, playername), String.class); if (result != null) { int i = fromIndex; @@ -68,7 +77,7 @@ public class HiScoreClient { try { hiScoreList.add(hiScoreBuilder.accept(osrsHiScoresStats, hiScoreStatValues, i)); } catch (EntityNotFoundException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } i++; } diff --git a/src/main/java/com/sxcy/sxcybot/config/AppConfig.java b/src/main/java/com/sxcy/sxcybot/config/AppConfig.java @@ -0,0 +1,15 @@ +package com.sxcy.sxcybot.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@SuppressWarnings("unused") +public class AppConfig { + + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } +} diff --git a/src/main/java/com/sxcy/sxcybot/enums/Command.java b/src/main/java/com/sxcy/sxcybot/enums/Command.java @@ -9,6 +9,7 @@ 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."), 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.PvmRoleCheckListener; import com.sxcy.sxcybot.listeners.member.RuleListener; import com.sxcy.sxcybot.listeners.member.RulesListener; import com.sxcy.sxcybot.listeners.member.StatsListener; @@ -60,6 +61,8 @@ public class CommandListener extends ListenerAdapter { private final PvmListListener pvmListListener; @NonNull private final HiscoreBossListener hiscoreBossListener; + @NonNull + private final PvmRoleCheckListener pvmRoleCheckListener; @Override public void onMessageReceived(@Nonnull MessageReceivedEvent event) { @@ -108,6 +111,9 @@ public class CommandListener extends ListenerAdapter { case BOSSLIST: hiscoreBossListener.proces(event); break; + case PVMCHECK: + pvmRoleCheckListener.proces(event); + break; case HELP: helpListener.proces(event); break; @@ -129,4 +135,4 @@ public class CommandListener extends ListenerAdapter { } return Optional.empty(); } -} -\ No newline at end of file +} diff --git a/src/main/java/com/sxcy/sxcybot/listeners/EventWaiterUtil.java b/src/main/java/com/sxcy/sxcybot/listeners/EventWaiterUtil.java @@ -15,12 +15,15 @@ import java.util.function.Predicate; @RequiredArgsConstructor public class EventWaiterUtil extends EventWaiter { + private static final int TIMEOUT = 1; + private static final TimeUnit TIME_UNIT = TimeUnit.MINUTES; + public void waitForPrivateChannelEvent(Consumer<PrivateMessageReceivedEvent> action, PrivateMessageReceivedEvent event, PrivateChannel privateChannel) { - waitForEvent(PrivateMessageReceivedEvent.class, verifyAuthor(event), action, 1, TimeUnit.MINUTES, new TimeOutRunner(privateChannel)); + waitForEvent(PrivateMessageReceivedEvent.class, verifyAuthor(event), action, TIMEOUT, TIME_UNIT, new TimeOutRunner(privateChannel)); } public void waitForPrivateChannelEvent(Consumer<PrivateMessageReceivedEvent> action, MessageReceivedEvent event, PrivateChannel privateChannel) { - waitForEvent(PrivateMessageReceivedEvent.class, verifyAuthor(event), action, 1, TimeUnit.MINUTES, new TimeOutRunner(privateChannel)); + waitForEvent(PrivateMessageReceivedEvent.class, verifyAuthor(event), action, TIMEOUT, TIME_UNIT, new TimeOutRunner(privateChannel)); } private Predicate<PrivateMessageReceivedEvent> verifyAuthor(MessageReceivedEvent event) { diff --git a/src/main/java/com/sxcy/sxcybot/listeners/GuildMemberEventListener.java b/src/main/java/com/sxcy/sxcybot/listeners/GuildMemberEventListener.java @@ -3,6 +3,7 @@ package com.sxcy.sxcybot.listeners; import com.sxcy.sxcybot.services.guild.GuildEventDmerService; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.PrivateChannel; import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; @@ -13,6 +14,7 @@ import org.springframework.stereotype.Component; import javax.annotation.Nonnull; import java.util.Optional; +@Slf4j @Component @RequiredArgsConstructor public class GuildMemberEventListener extends ListenerAdapter { @@ -31,7 +33,7 @@ public class GuildMemberEventListener extends ListenerAdapter { PrivateChannel privateChannel = member.get().getUser().openPrivateChannel().complete(true); privateChannel.sendMessage(String.format("**%s** has been removed from channel _%s_", event.getUser().getName(), event.getGuild().getName())).queue(); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/BanlistListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/BanlistListener.java @@ -6,6 +6,7 @@ import com.sxcy.sxcybot.services.guild.UserService; import com.sxcy.sxcybot.util.JdaUtil; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.PrivateChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; @@ -16,6 +17,7 @@ import java.awt.Color; import java.util.List; +@Slf4j @Component @RequiredArgsConstructor public class BanlistListener implements Listener { @@ -47,7 +49,7 @@ public class BanlistListener implements Listener { i++; } } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/EditBanlistListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/EditBanlistListener.java @@ -8,11 +8,13 @@ import com.sxcy.sxcybot.model.EditListenerDto; import com.sxcy.sxcybot.util.EditListenerUtil; import lombok.NonNull; 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 EditBanlistListener implements Listener { @@ -31,20 +33,18 @@ public class EditBanlistListener implements Listener { if (event.getMember() != null) { try { PrivateChannel privateChannel = event.getMember().getUser().openPrivateChannel().complete(true); - if (event.getMember() != null) { - EditListenerDto editListenerDto = EditListenerDto.builder() - .addListener(addBanlistUserListener) - .updateListener(updateBanlistListener) - .deleteListener(deleteBanlistListener) - .event(event) - .privateChannel(privateChannel) - .entityName("user to banlist") - .build(); - editListenerUtil.procesEditEvent(editListenerDto); - } + EditListenerDto editListenerDto = EditListenerDto.builder() + .addListener(addBanlistUserListener) + .updateListener(updateBanlistListener) + .deleteListener(deleteBanlistListener) + .event(event) + .privateChannel(privateChannel) + .entityName("user to banlist") + .build(); + editListenerUtil.procesEditEvent(editListenerDto); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } -} -\ No newline at end of file +} diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/EditPvmListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/EditPvmListener.java @@ -8,11 +8,13 @@ import com.sxcy.sxcybot.model.EditListenerDto; import com.sxcy.sxcybot.util.EditListenerUtil; import lombok.NonNull; 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 EditPvmListener implements Listener { @@ -31,19 +33,17 @@ public class EditPvmListener implements Listener { if (event.getMember() != null) { try { PrivateChannel privateChannel = event.getMember().getUser().openPrivateChannel().complete(true); - if (event.getMember() != null) { - EditListenerDto editListenerDto = EditListenerDto.builder() - .addListener(addPvmListener) - .updateListener(updatePvmListener) - .deleteListener(deletePvmListener) - .event(event) - .privateChannel(privateChannel) - .entityName("PvM competitor") - .build(); - editListenerUtil.procesEditEvent(editListenerDto); - } + EditListenerDto editListenerDto = EditListenerDto.builder() + .addListener(addPvmListener) + .updateListener(updatePvmListener) + .deleteListener(deletePvmListener) + .event(event) + .privateChannel(privateChannel) + .entityName("PvM competitor") + .build(); + editListenerUtil.procesEditEvent(editListenerDto); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/EditRoleListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/EditRoleListener.java @@ -8,11 +8,13 @@ import com.sxcy.sxcybot.model.EditListenerDto; import com.sxcy.sxcybot.util.EditListenerUtil; import lombok.NonNull; 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 EditRoleListener implements Listener { @@ -34,18 +36,18 @@ public class EditRoleListener implements Listener { if (event.getMember() != null) { try { PrivateChannel privateChannel = event.getMember().getUser().openPrivateChannel().complete(true); - if (event.getMember() != null) { - EditListenerDto editListenerDto = EditListenerDto.builder() - .addListener(addRoleListener) - .deleteListener(deleteRoleListener) - .event(event) - .privateChannel(privateChannel) - .entityName("role") - .build(); - editListenerUtil.procesEditEvent(editListenerDto); - } + EditListenerDto editListenerDto = EditListenerDto.builder() + .addListener(addRoleListener) + .deleteListener(deleteRoleListener) + //TODO why not implemented? +// .updateListener(updateRoleListener) + .event(event) + .privateChannel(privateChannel) + .entityName("role") + .build(); + editListenerUtil.procesEditEvent(editListenerDto); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/EditRuleListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/EditRuleListener.java @@ -8,11 +8,13 @@ import com.sxcy.sxcybot.model.EditListenerDto; import com.sxcy.sxcybot.util.EditListenerUtil; import lombok.NonNull; 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 EditRuleListener implements Listener { @@ -31,19 +33,17 @@ public class EditRuleListener implements Listener { if (event.getMember() != null) { try { PrivateChannel privateChannel = event.getMember().getUser().openPrivateChannel().complete(true); - if (event.getMember() != null) { - EditListenerDto editListenerDto = EditListenerDto.builder() - .addListener(addRuleListener) - .updateListener(updateRuleListener) - .deleteListener(deleteRuleListener) - .event(event) - .privateChannel(privateChannel) - .entityName("rule") - .build(); - editListenerUtil.procesEditEvent(editListenerDto); - } + EditListenerDto editListenerDto = EditListenerDto.builder() + .addListener(addRuleListener) + .updateListener(updateRuleListener) + .deleteListener(deleteRuleListener) + .event(event) + .privateChannel(privateChannel) + .entityName("rule") + .build(); + editListenerUtil.procesEditEvent(editListenerDto); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/RoleAssignListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/RoleAssignListener.java @@ -7,6 +7,7 @@ import com.sxcy.sxcybot.services.guild.GuildRoleService; import com.sxcy.sxcybot.util.DiscordMemberFinderUtil; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.PrivateChannel; import net.dv8tion.jda.api.entities.Role; @@ -22,6 +23,7 @@ import java.util.stream.Collectors; import static com.sxcy.sxcybot.util.Constants.ADDED_ROLE_ELEVATION; +@Slf4j @Component @RequiredArgsConstructor public class RoleAssignListener implements Listener { @@ -87,7 +89,7 @@ public class RoleAssignListener implements Listener { }); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/pvmrole/AddPvmListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/pvmrole/AddPvmListener.java @@ -4,7 +4,7 @@ import com.sxcy.sxcybot.exceptions.EntityNotFoundException; import com.sxcy.sxcybot.listeners.EventWaiterUtil; import com.sxcy.sxcybot.listeners.PrivateListener; import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; -import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleSnapshotComparerService; +import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleSnapshotComparatorService; import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleUserService; import com.sxcy.sxcybot.util.DiscordMemberFinderUtil; import com.sxcy.sxcybot.util.JdaUtil; @@ -30,7 +30,7 @@ public class AddPvmListener implements PrivateListener { @NonNull private final PvmRoleUserService pvmRoleUserService; @NonNull - private final PvmRoleSnapshotComparerService pvmRoleSnapshotComparerService; + private final PvmRoleSnapshotComparatorService pvmRoleSnapshotComparatorService; @Override public void proces(PrivateMessageReceivedEvent privateMessageReceivedEvent, MessageReceivedEvent event) { @@ -57,7 +57,7 @@ public class AddPvmListener implements PrivateListener { privateChannel.sendMessage(String.format("%s (RSN: %s) has been succesfully added!", member, pvmRoleUser.getRsn())).queue(); try { - pvmRoleSnapshotComparerService.saveSnapshot(event.getChannel(), pvmRoleUser, true); + pvmRoleSnapshotComparatorService.takeSnapshot(event.getChannel(), pvmRoleUser, true, true); } catch (EntityNotFoundException e) { event.getChannel().sendMessage(e.getMessage()).queue(); } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/role/DeleteRoleListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/role/DeleteRoleListener.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Component; import java.util.stream.Collectors; import static com.sxcy.sxcybot.util.Constants.ADDED_ROLE_ELEVATION; +import static com.sxcy.sxcybot.util.Constants.Commands.COMMAND_PREFIX; @Component @RequiredArgsConstructor @@ -40,7 +41,7 @@ public class DeleteRoleListener implements PrivateListener { privateChannel.sendMessage(String.format("%s succesfully deleted.", guildRole)).queue(); event.getChannel().sendMessage(String.format("Role %s has been deleted by %s", guildRole, JdaUtil.getUser(event))).queue(); } else { - privateChannel.sendMessage("Only roles that can be added with the bb-role command can be deleted.").queue(); + privateChannel.sendMessage(String.format("Only roles that can be added with the %srole command can be deleted.", COMMAND_PREFIX)).queue(); } } catch (EntityNotFoundException e) { privateChannel.sendMessage(e.getMessage()).queue(); diff --git a/src/main/java/com/sxcy/sxcybot/listeners/admin/role/UpdateRoleListener.java b/src/main/java/com/sxcy/sxcybot/listeners/admin/role/UpdateRoleListener.java @@ -14,6 +14,7 @@ import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent; import org.springframework.stereotype.Component; import static com.sxcy.sxcybot.util.Constants.ADDED_ROLE_ELEVATION; +import static com.sxcy.sxcybot.util.Constants.Commands.COMMAND_PREFIX; @Component @RequiredArgsConstructor @@ -42,7 +43,7 @@ public class UpdateRoleListener implements PrivateListener { newRoleNameReceiver.getChannel().sendMessage(guildRole + " edited").queue(); event.getChannel().sendMessage(String.format("Role %s has been changed to %s by %s", roleName, newRoleNameReceiver.getMessage().getContentRaw(), JdaUtil.getUser(event))).queue(); } else { - privateChannel.sendMessage("Only roles that can be added with the bb-role command can be updated.").queue(); + privateChannel.sendMessage(String.format("Only roles that can be added with the %srole command can be updated.", COMMAND_PREFIX)).queue(); } } catch (EntityNotFoundException exc) { oldRoleNameReceiver.getChannel().sendMessage(exc.getMessage()).queue(); diff --git a/src/main/java/com/sxcy/sxcybot/listeners/member/CustomPollListener.java b/src/main/java/com/sxcy/sxcybot/listeners/member/CustomPollListener.java @@ -4,6 +4,7 @@ import com.sxcy.sxcybot.listeners.Listener; import com.sxcy.sxcybot.util.CustomPollFiller; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.PrivateChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; @@ -15,6 +16,7 @@ import org.springframework.stereotype.Component; import java.awt.Color; import java.util.LinkedHashSet; +@Slf4j @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) @RequiredArgsConstructor @@ -37,11 +39,11 @@ public class CustomPollListener implements Listener { customPollFiller.fillPoll(privateChannel, event, embedBuilder, new LinkedHashSet<>()); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } catch (StringIndexOutOfBoundsException e) { event.getChannel().sendMessage("Please enter a descriptive title for the poll after the command, separated by space.").queue(); } } -} -\ No newline at end of file +} diff --git a/src/main/java/com/sxcy/sxcybot/listeners/member/EventListener.java b/src/main/java/com/sxcy/sxcybot/listeners/member/EventListener.java @@ -5,12 +5,14 @@ import com.sxcy.sxcybot.listeners.Listener; import com.sxcy.sxcybot.repository.guild.dao.Event; import lombok.NonNull; 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.events.message.priv.PrivateMessageReceivedEvent; import net.dv8tion.jda.api.exceptions.RateLimitedException; import org.springframework.stereotype.Component; +@Slf4j @Component @RequiredArgsConstructor public class EventListener implements Listener { @@ -36,7 +38,7 @@ public class EventListener implements Listener { }, event, privateChannel); }, event, privateChannel); } catch (RateLimitedException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } } diff --git a/src/main/java/com/sxcy/sxcybot/listeners/member/PriceListener.java b/src/main/java/com/sxcy/sxcybot/listeners/member/PriceListener.java @@ -26,10 +26,10 @@ public class PriceListener implements Listener { String itemName = msg.substring(msg.indexOf(" ")).trim(); event.getChannel().sendTyping().queue(typing -> { try { - Object result = grandExchangeClient.getPrice(itemName, event.getChannel()); + String result = grandExchangeClient.getPrice(itemName, event.getChannel()); embedBuilder.setTitle("Price of item"); embedBuilder.setColor(Color.RED); - embedBuilder.addField(itemName, result.toString(), false); + embedBuilder.addField(itemName, result, false); event.getChannel().sendMessage(embedBuilder.build()).queue(); } catch (EntityNotFoundException e) { event.getChannel().sendMessage(e.getMessage()).queue(); diff --git a/src/main/java/com/sxcy/sxcybot/listeners/member/PvmRoleCheckListener.java b/src/main/java/com/sxcy/sxcybot/listeners/member/PvmRoleCheckListener.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 PvmRoleCheckListener 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/model/CombatDto.java b/src/main/java/com/sxcy/sxcybot/model/CombatDto.java @@ -17,7 +17,6 @@ import static com.sxcy.sxcybot.enums.OsrsCombatStat.STRENGTH; @Builder(toBuilder = true) public class CombatDto { - int attackLevel; int strengthLevel; int defenceLevel; diff --git a/src/main/java/com/sxcy/sxcybot/model/EditListenerDto.java b/src/main/java/com/sxcy/sxcybot/model/EditListenerDto.java @@ -7,8 +7,8 @@ import lombok.Value; import net.dv8tion.jda.api.entities.PrivateChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -@Builder(toBuilder = true) @Value +@Builder(toBuilder = true) public class EditListenerDto { @NonNull diff --git a/src/main/java/com/sxcy/sxcybot/services/PvMRoleResolver.java b/src/main/java/com/sxcy/sxcybot/services/PvMRoleResolver.java @@ -0,0 +1,73 @@ +package com.sxcy.sxcybot.services; + +import com.sxcy.sxcybot.enums.PvmRole; +import com.sxcy.sxcybot.exceptions.EntityNotFoundException; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmKcSnapshot; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; +import com.sxcy.sxcybot.services.guild.ChannelDetailService; +import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleAssignerService; +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 net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.PrivateChannel; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static com.google.common.collect.Lists.newArrayList; + +@Component +@RequiredArgsConstructor +public class PvMRoleResolver { + + @NonNull + private final PvmRoleUserService pvmRoleUserService; + @NonNull + private final ChannelDetailService channelDetailService; + @NonNull + private final PvmRoleSnapshotComparatorService pvmRoleSnapshotComparatorService; + @NonNull + private final PvmRoleAssignerService pvmRoleAssignerService; + @Setter + private JDA jda; + + @Scheduled(cron = "${pvm.role.schedule}") + @SuppressWarnings("unused") + public void resolvePvMRoles() { + resolvePvMRoles(true, null); + } + + public void resolvePvMRoles(boolean persist, PrivateChannel privateChannel) { + Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard = new HashMap<>(); + for (PvmRole pvmRole : PvmRole.values()) { + if (!pvmRole.equals(PvmRole.UNUSED)) + scoreBoard.put(pvmRole, new LinkedHashMap<>()); + } + jda.getGuilds().forEach(guild -> + channelDetailService.findAll().stream().findAny().ifPresent(channelDetail -> + (privateChannel == null ? guild.getTextChannelsByName(channelDetail.getPvmRoleChannel(), true) : newArrayList(privateChannel)) + .forEach(textChannel -> { + for (PvmRoleUser pvmRoleUser : pvmRoleUserService.findAll()) { + List<PvmKcSnapshot> pvmKcSnapshots = new ArrayList<>(); + try { + pvmKcSnapshots.add(pvmRoleSnapshotComparatorService.takeSnapshot(textChannel, pvmRoleUser, false, persist)); + } catch (EntityNotFoundException e) { + textChannel.sendMessage(e.getMessage()).queue(); + } + pvmRoleSnapshotComparatorService.updateScoreboard(pvmRoleUser, scoreBoard, persist ? null : pvmKcSnapshots); + } + pvmRoleAssignerService.postScoreboardAndAssignRoles(guild, textChannel, scoreBoard, channelDetail, persist); + }) + ) + ); + } +} diff --git a/src/main/java/com/sxcy/sxcybot/services/PvMRoleScheduler.java b/src/main/java/com/sxcy/sxcybot/services/PvMRoleScheduler.java @@ -1,61 +0,0 @@ -package com.sxcy.sxcybot.services; - -import com.sxcy.sxcybot.enums.PvmRole; -import com.sxcy.sxcybot.exceptions.EntityNotFoundException; -import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; -import com.sxcy.sxcybot.services.guild.ChannelDetailService; -import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleAssignerService; -import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleSnapshotComparerService; -import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleUserService; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import net.dv8tion.jda.api.JDA; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.math.BigDecimal; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -@Component -@RequiredArgsConstructor -public class PvMRoleScheduler { - - @NonNull - private final PvmRoleUserService pvmRoleUserService; - @NonNull - private final ChannelDetailService channelDetailService; - @NonNull - private final PvmRoleSnapshotComparerService pvmRoleSnapshotComparerService; - @NonNull - private final PvmRoleAssignerService pvmRoleAssignerService; - @Setter - private JDA jda; - - @Scheduled(cron = "${pvm.role.schedule}") - @SuppressWarnings("unused") - public void resolvePvMRoles() { - Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard = new HashMap<>(); - for (PvmRole pvmRole : PvmRole.values()) { - scoreBoard.put(pvmRole, new LinkedHashMap<>()); - } - jda.getGuilds().forEach(guild -> - channelDetailService.findAll().stream().findAny().ifPresent(channelDetail -> - guild.getTextChannelsByName(channelDetail.getPvmRoleChannel(), true) - .forEach(textChannel -> { - for (PvmRoleUser pvmRoleUser : pvmRoleUserService.findAll()) { - try { - pvmRoleSnapshotComparerService.saveSnapshot(textChannel, pvmRoleUser, false); - } catch (EntityNotFoundException e) { - textChannel.sendMessage(e.getMessage()).queue(); - } - pvmRoleSnapshotComparerService.updateScoreboard(pvmRoleUser, scoreBoard); - } - pvmRoleAssignerService.postScoreboardAndAssignRoles(guild, textChannel, scoreBoard, channelDetail); - }) - ) - ); - } -} diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleAssignerService.java b/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleAssignerService.java @@ -12,6 +12,6 @@ import java.util.Map; public interface PvmRoleAssignerService { - void postScoreboardAndAssignRoles(Guild guild, MessageChannel textChannel, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard, ChannelDetail channelDetail); + void postScoreboardAndAssignRoles(Guild guild, MessageChannel textChannel, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard, ChannelDetail channelDetail, boolean persist); } diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleSnapshotComparatorService.java b/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleSnapshotComparatorService.java @@ -0,0 +1,19 @@ +package com.sxcy.sxcybot.services.guild.pvmrole; + +import com.sxcy.sxcybot.enums.PvmRole; +import com.sxcy.sxcybot.exceptions.EntityNotFoundException; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmKcSnapshot; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; +import net.dv8tion.jda.api.entities.MessageChannel; + +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public interface PvmRoleSnapshotComparatorService { + + void updateScoreboard(PvmRoleUser pvmRoleUser, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard, List<PvmKcSnapshot> unpersisted); + + PvmKcSnapshot takeSnapshot(MessageChannel textChannel, PvmRoleUser pvmRoleUser, boolean notify, boolean persist) throws EntityNotFoundException; +} diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleSnapshotComparerService.java b/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/PvmRoleSnapshotComparerService.java @@ -1,17 +0,0 @@ -package com.sxcy.sxcybot.services.guild.pvmrole; - -import com.sxcy.sxcybot.enums.PvmRole; -import com.sxcy.sxcybot.exceptions.EntityNotFoundException; -import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; -import net.dv8tion.jda.api.entities.MessageChannel; - -import java.math.BigDecimal; -import java.util.LinkedHashMap; -import java.util.Map; - -public interface PvmRoleSnapshotComparerService { - - void updateScoreboard(PvmRoleUser pvmRoleUser, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard); - - void saveSnapshot(MessageChannel textChannel, PvmRoleUser pvmRoleUser, boolean notify) throws EntityNotFoundException; -} diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleAssignerServiceImpl.java b/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleAssignerServiceImpl.java @@ -28,7 +28,7 @@ import java.util.Optional; public class PvmRoleAssignerServiceImpl implements PvmRoleAssignerService { @Override - public void postScoreboardAndAssignRoles(Guild guild, MessageChannel textChannel, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard, ChannelDetail channelDetail) { + public void postScoreboardAndAssignRoles(Guild guild, MessageChannel textChannel, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard, ChannelDetail channelDetail, boolean persist) { for (PvmRole pvmRole : scoreBoard.keySet()) { String rolename = getRolename(pvmRole, channelDetail); EmbedBuilder embedBuilder = new EmbedBuilder(); @@ -51,7 +51,7 @@ public class PvmRoleAssignerServiceImpl implements PvmRoleAssignerService { Optional<Member> member = memberlist.stream().filter(f -> entry.getKey().getDiscordName().equalsIgnoreCase(f.getUser().getName()) || entry.getKey().getDiscordName().equalsIgnoreCase(f.getNickname())).findFirst(); if (member.isPresent()) { embedBuilder.addField(String.format("#%s %s", i, entry.getKey().getRsn()), String.format("%s with a score of %s!", member.get(), entry.getValue()), false); - if (i == 1) { + if (i == 1 && persist) { Optional<Role> role = guild.getRoles().stream().filter(f -> rolename.equalsIgnoreCase(f.getName())).findFirst(); if (role.isPresent()) { guild.findMembersWithRoles(role.get()) diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleSnapshotComparatorServiceImpl.java b/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleSnapshotComparatorServiceImpl.java @@ -0,0 +1,101 @@ +package com.sxcy.sxcybot.services.guild.pvmrole.impl; + +import com.sxcy.sxcybot.client.HiScoreClient; +import com.sxcy.sxcybot.enums.PvmRole; +import com.sxcy.sxcybot.exceptions.EntityNotFoundException; +import com.sxcy.sxcybot.model.OsrsBossKc; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmKcSnapshot; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; +import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmUserKc; +import com.sxcy.sxcybot.services.guild.pvmrole.PvmKcSnapshotService; +import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleSnapshotComparatorService; +import com.sxcy.sxcybot.services.osrs.OsrsHiscoreBossService; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.dv8tion.jda.api.entities.MessageChannel; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Service +@Transactional +@RequiredArgsConstructor +public class PvmRoleSnapshotComparatorServiceImpl implements PvmRoleSnapshotComparatorService { + + @NonNull + private final OsrsHiscoreBossService osrsHiscoreBossService; + @NonNull + private final PvmKcSnapshotService pvmKcSnapshotService; + @NonNull + private final HiScoreClient hiScoreClient; + + @Override + public void updateScoreboard(PvmRoleUser pvmRoleUser, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard, List<PvmKcSnapshot> unpersistedSnapshots) { + boolean persisted = unpersistedSnapshots == null; + List<PvmKcSnapshot> pvmKcSnapshots = pvmKcSnapshotService.findAllByPvmRoleUser(pvmRoleUser); + if (pvmKcSnapshots != null && (pvmKcSnapshots.size() > 1 || (!persisted && pvmKcSnapshots.size() > 0))) { + pvmKcSnapshots = pvmKcSnapshots.stream() + .sorted(Comparator.comparing(PvmKcSnapshot::getCreatedDate) + .reversed()) + .limit(persisted ? 2 : 1) + .collect(Collectors.toList()); + for (PvmRole pvmRole : PvmRole.values()) { + BigDecimal points1 = calculatePoints(pvmRole, persisted ? pvmKcSnapshots.get(0) : unpersistedSnapshots.get(0)); + BigDecimal points2 = calculatePoints(pvmRole, pvmKcSnapshots.get(persisted ? 1 : 0)); + BigDecimal result = points1.subtract(points2); + if (BigDecimal.ZERO.compareTo(result) < 0) + scoreBoard.get(pvmRole).put(pvmRoleUser, result); + } + } + } + + private BigDecimal calculatePoints(PvmRole pvmRole, PvmKcSnapshot pvmKcSnapshot) { + BigDecimal points = BigDecimal.ZERO; + for (PvmUserKc pvmUserKc : pvmKcSnapshot.getPvmUserKcList().stream().filter(f -> pvmRole.value == f.getOsrsHiscoreBoss().getPvmRole()).collect(Collectors.toList())) { + points = points.add(BigDecimal.valueOf(pvmUserKc.getOsrsHiscoreBoss().getMultiplier()).multiply(BigDecimal.valueOf(pvmUserKc.getKc()))); + } + return points; + } + + @Override + public PvmKcSnapshot takeSnapshot(MessageChannel textChannel, PvmRoleUser pvmRoleUser, boolean notify, boolean persist) throws EntityNotFoundException { + PvmKcSnapshot pvmKcSnapshot = PvmKcSnapshot.builder() + .pvmRoleUser(pvmRoleUser) + .build(); + List<OsrsBossKc> osrsBossKcList = hiScoreClient.getHiScoreBossKc(pvmRoleUser.getRsn(), textChannel).orElseThrow( + () -> new EntityNotFoundException(String.format("No hiScores found for %s", pvmRoleUser.getRsn())) + ); + List<PvmUserKc> pvmUserKcList = new ArrayList<>(); + for (OsrsBossKc osrsBossKc : osrsBossKcList.stream().filter(r -> Integer.parseInt(r.getKc()) > 0).collect(Collectors.toList())) { + try { + PvmUserKc pvmUserKc = PvmUserKc.builder() + .pvmRoleUser(pvmRoleUser) + .osrsHiscoreBoss(osrsHiscoreBossService.findByName(osrsBossKc.getName())) + .pvmKcSnapshot(pvmKcSnapshot) + .kc(Integer.valueOf(osrsBossKc.getKc())) + .build(); + pvmUserKcList.add(pvmUserKc); + } catch (EntityNotFoundException e) { + log.error(e.getMessage(), e); + } + } + pvmKcSnapshot.setPvmUserKcList(pvmUserKcList); + + if (persist) { + pvmKcSnapshot = pvmKcSnapshotService.save(pvmKcSnapshot); + if (notify) + textChannel.sendMessage(String.format("KC snapshot saved for %s.%n", pvmRoleUser.getRsn())).queue(); + } + + return pvmKcSnapshot; + } +} diff --git a/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleSnapshotComparerServiceImpl.java b/src/main/java/com/sxcy/sxcybot/services/guild/pvmrole/impl/PvmRoleSnapshotComparerServiceImpl.java @@ -1,93 +0,0 @@ -package com.sxcy.sxcybot.services.guild.pvmrole.impl; - -import com.sxcy.sxcybot.client.HiScoreClient; -import com.sxcy.sxcybot.enums.PvmRole; -import com.sxcy.sxcybot.exceptions.EntityNotFoundException; -import com.sxcy.sxcybot.model.OsrsBossKc; -import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmKcSnapshot; -import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmRoleUser; -import com.sxcy.sxcybot.repository.guild.pvmrole.dao.PvmUserKc; -import com.sxcy.sxcybot.services.guild.pvmrole.PvmKcSnapshotService; -import com.sxcy.sxcybot.services.guild.pvmrole.PvmRoleSnapshotComparerService; -import com.sxcy.sxcybot.services.osrs.OsrsHiscoreBossService; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import net.dv8tion.jda.api.entities.MessageChannel; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Service -@Transactional -@RequiredArgsConstructor -public class PvmRoleSnapshotComparerServiceImpl implements PvmRoleSnapshotComparerService { - - @NonNull - private final OsrsHiscoreBossService osrsHiscoreBossService; - @NonNull - private final PvmKcSnapshotService pvmKcSnapshotService; - @NonNull - private final HiScoreClient hiScoreClient; - - @Override - public void updateScoreboard(PvmRoleUser pvmRoleUser, Map<PvmRole, LinkedHashMap<PvmRoleUser, BigDecimal>> scoreBoard) { - List<PvmKcSnapshot> pvmKcSnapshots = pvmKcSnapshotService.findAllByPvmRoleUser(pvmRoleUser); - if (pvmKcSnapshots != null && pvmKcSnapshots.size() > 1) { - pvmKcSnapshots = pvmKcSnapshots.stream() - .sorted(Comparator.comparing(PvmKcSnapshot::getCreatedDate) - .reversed()) - .limit(2) - .collect(Collectors.toList()); - for (PvmRole pvmRole : PvmRole.values()) { - BigDecimal points1 = calculatePoints(pvmRole, pvmKcSnapshots.get(0)); - BigDecimal points2 = calculatePoints(pvmRole, pvmKcSnapshots.get(1)); - BigDecimal result = points1.subtract(points2); - if (BigDecimal.ZERO.compareTo(result) < 0) - scoreBoard.get(pvmRole).put(pvmRoleUser, result); - } - } - } - - private BigDecimal calculatePoints(PvmRole pvmRole, PvmKcSnapshot pvmKcSnapshot) { - BigDecimal points = BigDecimal.ZERO; - for (PvmUserKc pvmUserKc : pvmKcSnapshot.getPvmUserKcList().stream().filter(f -> pvmRole.value == f.getOsrsHiscoreBoss().getPvmRole()).collect(Collectors.toList())) { - points = points.add(BigDecimal.valueOf(pvmUserKc.getOsrsHiscoreBoss().getMultiplier()).multiply(BigDecimal.valueOf(pvmUserKc.getKc()))); - } - return points; - } - - @Override - public void saveSnapshot(MessageChannel textChannel, PvmRoleUser pvmRoleUser, boolean notify) throws EntityNotFoundException { - PvmKcSnapshot pvmKcSnapshot = PvmKcSnapshot.builder() - .pvmRoleUser(pvmRoleUser) - .build(); - List<OsrsBossKc> osrsBossKcList = hiScoreClient.getHiScoreBossKc(pvmRoleUser.getRsn(), textChannel).orElseThrow( - () -> new EntityNotFoundException(String.format("No hiScores found for %s", pvmRoleUser.getRsn())) - ); - List<PvmUserKc> pvmUserKcList = new ArrayList<>(); - for (OsrsBossKc osrsBossKc : osrsBossKcList.stream().filter(r -> Integer.parseInt(r.getKc()) > 0).collect(Collectors.toList())) { - try { - PvmUserKc pvmUserKc = PvmUserKc.builder() - .pvmRoleUser(pvmRoleUser) - .osrsHiscoreBoss(osrsHiscoreBossService.findByName(osrsBossKc.getName())) - .pvmKcSnapshot(pvmKcSnapshot) - .kc(Integer.valueOf(osrsBossKc.getKc())) - .build(); - pvmUserKcList.add(pvmUserKc); - } catch (EntityNotFoundException e) { - e.printStackTrace(); - } - } - pvmKcSnapshot.setPvmUserKcList(pvmUserKcList); - pvmKcSnapshotService.save(pvmKcSnapshot); - if (notify) - textChannel.sendMessage(String.format("KC snapshot saved for %s.%n", pvmRoleUser.getRsn())).queue(); - } -} diff --git a/src/main/resources/releasenotes.csv b/src/main/resources/releasenotes.csv @@ -1 +1 @@ -Changed releasenotes generation;Releasenotes are now generated by csv file instead of in-line code. +Added sb-pvmcheck command;This command shows the current hiscores of the PvM Role competition through DM.