From bb08e3b614fb06b95329aa7172fbc14f0f25a252 Mon Sep 17 00:00:00 2001 From: Sebastien Date: Wed, 5 Dec 2018 21:53:48 +0200 Subject: [PATCH] Add user stats mechanism --- src/main/java/net/Broken/BotListener.java | 18 +- .../java/net/Broken/DB/Entity/UserEntity.java | 15 ++ .../java/net/Broken/DB/Entity/UserStats.java | 84 +++++++++ .../Repository/GuildPreferenceRepository.java | 1 + .../DB/Repository/UserStatsRepository.java | 13 ++ src/main/java/net/Broken/Init.java | 25 +++ .../Broken/RestApi/MusicWebAPIController.java | 6 +- .../Tools/UserManager/UserStatsUtils.java | 172 ++++++++++++++++++ 8 files changed, 327 insertions(+), 7 deletions(-) create mode 100644 src/main/java/net/Broken/DB/Entity/UserStats.java create mode 100644 src/main/java/net/Broken/DB/Repository/UserStatsRepository.java create mode 100644 src/main/java/net/Broken/Tools/UserManager/UserStatsUtils.java diff --git a/src/main/java/net/Broken/BotListener.java b/src/main/java/net/Broken/BotListener.java index 0891430..ef7b53a 100644 --- a/src/main/java/net/Broken/BotListener.java +++ b/src/main/java/net/Broken/BotListener.java @@ -1,23 +1,22 @@ package net.Broken; import net.Broken.Commands.Move; -import net.Broken.Commands.Music; import net.Broken.DB.Entity.GuildPreferenceEntity; import net.Broken.DB.Repository.GuildPreferenceRepository; -import net.Broken.DB.Repository.PlaylistRepository; import net.Broken.Tools.AntiSpam; import net.Broken.Tools.Command.CommandParser; import net.Broken.Tools.EmbedMessageUtils; import net.Broken.Tools.Moderateur; import net.Broken.Tools.PrivateMessage; +import net.Broken.Tools.UserManager.UserStatsUtils; import net.Broken.audio.AudioM; import net.dv8tion.jda.core.EmbedBuilder; import net.dv8tion.jda.core.entities.*; -import net.dv8tion.jda.core.events.ExceptionEvent; import net.dv8tion.jda.core.events.ReadyEvent; import net.dv8tion.jda.core.events.guild.GuildJoinEvent; import net.dv8tion.jda.core.events.guild.member.GuildMemberJoinEvent; import net.dv8tion.jda.core.events.guild.member.GuildMemberRoleRemoveEvent; +import net.dv8tion.jda.core.events.guild.voice.GuildVoiceJoinEvent; import net.dv8tion.jda.core.events.guild.voice.GuildVoiceLeaveEvent; import net.dv8tion.jda.core.events.message.MessageReceivedEvent; import net.dv8tion.jda.core.hooks.ListenerAdapter; @@ -121,6 +120,13 @@ public class BotListener extends ListenerAdapter { } + @Override + public void onGuildVoiceJoin(GuildVoiceJoinEvent event) { + super.onGuildVoiceJoin(event); + if(!event.getMember().getUser().isBot()) + new UserStatsUtils.VoicePresenceCompter(event.getMember()).start(); + } + @Override public void onGuildVoiceLeave(GuildVoiceLeaveEvent event) { super.onGuildVoiceLeave(event); @@ -138,9 +144,9 @@ public class BotListener extends ListenerAdapter { @Override public void onMessageReceived(MessageReceivedEvent event) { - // ----------------------Preference pour eviter eco de commande------------------------- - - + if(!event.getAuthor().isBot()){ + UserStatsUtils.getINSTANCE().addMessageCount(event.getMember()); + } try{ if (event.getMessage().getContentRaw().startsWith("//") && !event.getMessage().getAuthor().getId().equals(event.getJDA().getSelfUser().getId())) { //On a detecter que c'etait une commande diff --git a/src/main/java/net/Broken/DB/Entity/UserEntity.java b/src/main/java/net/Broken/DB/Entity/UserEntity.java index 81df664..e642dc2 100644 --- a/src/main/java/net/Broken/DB/Entity/UserEntity.java +++ b/src/main/java/net/Broken/DB/Entity/UserEntity.java @@ -25,12 +25,18 @@ public class UserEntity { private String apiToken; + @JsonIgnore + @OneToMany(fetch = FetchType.EAGER, mappedBy = "user") + private List userStats; + @JsonIgnore private String password; + @OneToMany(mappedBy = "user") private List playlists; + public UserEntity() { } @@ -55,6 +61,7 @@ public class UserEntity { this.password = passwordEncoder.encode(UserUtils.getInstance().generateCheckToken()); } + public String getPassword() { return password; } @@ -109,4 +116,12 @@ public class UserEntity { this.playlists.addAll(Arrays.asList(playlists)); } + + public List getUserStats() { + return userStats; + } + + public void setUserStats(List userStats) { + this.userStats = userStats; + } } diff --git a/src/main/java/net/Broken/DB/Entity/UserStats.java b/src/main/java/net/Broken/DB/Entity/UserStats.java new file mode 100644 index 0000000..c11cac7 --- /dev/null +++ b/src/main/java/net/Broken/DB/Entity/UserStats.java @@ -0,0 +1,84 @@ +package net.Broken.DB.Entity; + +import org.hibernate.annotations.ColumnDefault; + +import javax.persistence.*; + +@Entity +public class UserStats { + + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private Long id; + + + private String guildId; + + @ManyToOne + @JoinColumn(name="userEntity_id", nullable=false) + private UserEntity user; + + @ColumnDefault("0") + private Long vocalTime = 0L; + + @ColumnDefault("0") + private Long messageCount = 0L; + + @ColumnDefault("0") + private Long apiCommandCount = 0L; + + public UserStats(){} + + public UserStats(String guildId, UserEntity user){ + this.guildId = guildId; + this.user = user; + } + + public UserEntity getUser() { + return user; + } + + public void setUser(UserEntity user) { + this.user = user; + } + + public Long getVocalTime() { + return vocalTime; + } + + public void setVocalTime(Long vocalTime) { + this.vocalTime = vocalTime; + } + + public Long getMessageCount() { + return messageCount; + } + + public void setMessageCount(Long messageCount) { + this.messageCount = messageCount; + } + + public Long getApiCommandCount() { + return apiCommandCount; + } + + public void setApiCommandCount(Long apiCommandCount) { + this.apiCommandCount = apiCommandCount; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getGuildId() { + return guildId; + } + + public void setGuildId(String guildId) { + this.guildId = guildId; + } +} diff --git a/src/main/java/net/Broken/DB/Repository/GuildPreferenceRepository.java b/src/main/java/net/Broken/DB/Repository/GuildPreferenceRepository.java index 336130d..f27973c 100644 --- a/src/main/java/net/Broken/DB/Repository/GuildPreferenceRepository.java +++ b/src/main/java/net/Broken/DB/Repository/GuildPreferenceRepository.java @@ -7,4 +7,5 @@ import java.util.List; public interface GuildPreferenceRepository extends CrudRepository { List findByGuildId(String id); + } diff --git a/src/main/java/net/Broken/DB/Repository/UserStatsRepository.java b/src/main/java/net/Broken/DB/Repository/UserStatsRepository.java new file mode 100644 index 0000000..87880fb --- /dev/null +++ b/src/main/java/net/Broken/DB/Repository/UserStatsRepository.java @@ -0,0 +1,13 @@ +package net.Broken.DB.Repository; + +import net.Broken.DB.Entity.UserEntity; +import net.Broken.DB.Entity.UserStats; +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + +public interface UserStatsRepository extends CrudRepository { + List findByUser(UserEntity userEntity); + List findByGuildId(String guildId); + List findByUserAndGuildId(UserEntity user, String guildId); +} diff --git a/src/main/java/net/Broken/Init.java b/src/main/java/net/Broken/Init.java index 232fdd5..05cbee2 100644 --- a/src/main/java/net/Broken/Init.java +++ b/src/main/java/net/Broken/Init.java @@ -1,10 +1,14 @@ package net.Broken; +import net.Broken.DB.Entity.UserEntity; +import net.Broken.DB.Entity.UserStats; +import net.Broken.DB.Repository.UserRepository; import net.Broken.RestApi.ApiCommandLoader; import net.Broken.Tools.Command.CommandLoader; import net.Broken.Tools.DayListener.DayListener; import net.Broken.Tools.DayListener.Listeners.DailyMadame; import net.Broken.Tools.DayListener.Listeners.ResetSpam; +import net.Broken.Tools.UserManager.UserStatsUtils; import net.Broken.audio.Youtube.YoutubeTools; import net.dv8tion.jda.core.AccountType; import net.dv8tion.jda.core.JDA; @@ -19,6 +23,7 @@ import net.dv8tion.jda.core.exceptions.RateLimitedException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.JSONObject; +import org.springframework.context.ApplicationContext; import javax.security.auth.login.LoginException; import java.io.IOException; @@ -83,6 +88,8 @@ public class Init { static void polish(JDA jda){ + logger.info("Check database..."); + checkDatabase(); CommandLoader.load(); ApiCommandLoader.load(); DayListener dayListener = DayListener.getInstance(); @@ -91,8 +98,26 @@ public class Init { dayListener.start(); jda.addEventListener(new BotListener()); jda.getPresence().setPresence(OnlineStatus.ONLINE, Game.playing(MainBot.url)); + + logger.info("-----------------------END INIT-----------------------"); + } + + + private static void checkDatabase(){ + ApplicationContext context = SpringContext.getAppContext(); + UserRepository userRepository = (UserRepository) context.getBean("userRepository"); + List users = (List) userRepository.findAll(); + UserStatsUtils userStatsUtils = UserStatsUtils.getINSTANCE(); + logger.debug("Stats..."); + for(UserEntity userEntity : users){ + logger.debug("..." + userEntity.getName()); + userStatsUtils.getUserStats(userEntity); + + } + + } } diff --git a/src/main/java/net/Broken/RestApi/MusicWebAPIController.java b/src/main/java/net/Broken/RestApi/MusicWebAPIController.java index 8a77a00..1e508ec 100644 --- a/src/main/java/net/Broken/RestApi/MusicWebAPIController.java +++ b/src/main/java/net/Broken/RestApi/MusicWebAPIController.java @@ -4,10 +4,12 @@ import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import net.Broken.DB.Entity.UserEntity; +import net.Broken.DB.Entity.UserStats; import net.Broken.DB.Repository.UserRepository; import net.Broken.MainBot; import net.Broken.RestApi.Data.*; import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException; +import net.Broken.Tools.UserManager.UserStatsUtils; import net.Broken.Tools.UserManager.UserUtils; import net.Broken.audio.AudioM; import net.Broken.audio.GetVoiceChanels; @@ -156,8 +158,10 @@ public class MusicWebAPIController { UserEntity user = userUtils.getUserWithApiToken(userRepository, token); logger.info("Receive command " + data.command + " from " + request.getRemoteAddr() + " USER: " + user.getName() + " GUILD: " + guild.getName()); - if (ApiCommandLoader.apiCommands.containsKey(data.command)) + if (ApiCommandLoader.apiCommands.containsKey(data.command)) { + UserStatsUtils.getINSTANCE().addApiCount(user, guildId); return ApiCommandLoader.apiCommands.get(data.command).action(data, MainBot.jda.getUserById(user.getJdaId()), guild); + } else return new ResponseEntity<>(new CommandResponseData(data.command, "Unknown Command", "command"), HttpStatus.BAD_REQUEST); diff --git a/src/main/java/net/Broken/Tools/UserManager/UserStatsUtils.java b/src/main/java/net/Broken/Tools/UserManager/UserStatsUtils.java new file mode 100644 index 0000000..b1803b2 --- /dev/null +++ b/src/main/java/net/Broken/Tools/UserManager/UserStatsUtils.java @@ -0,0 +1,172 @@ +package net.Broken.Tools.UserManager; + +import net.Broken.DB.Entity.UserEntity; +import net.Broken.DB.Entity.UserStats; +import net.Broken.DB.Repository.UserRepository; +import net.Broken.DB.Repository.UserStatsRepository; +import net.Broken.MainBot; +import net.Broken.SpringContext; +import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.Member; +import net.dv8tion.jda.core.entities.User; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.hibernate.Hibernate; +import org.springframework.context.ApplicationContext; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.ArrayList; +import java.util.List; + +public class UserStatsUtils { + + + private static UserStatsUtils INSTANCE = new UserStatsUtils(); + + public static UserStatsUtils getINSTANCE() { + return INSTANCE; + } + + private UserStatsRepository userStatsRepository; + private UserRepository userRepository; + private PasswordEncoder passwordEncoder; + + private Logger logger = LogManager.getLogger(); + + + + private UserStatsUtils(){ + ApplicationContext context = SpringContext.getAppContext(); + userStatsRepository = (UserStatsRepository) context.getBean("userStatsRepository"); + userRepository = (UserRepository) context.getBean("userRepository"); + passwordEncoder = (PasswordEncoder) context.getBean("passwordEncoder"); + + } + + public List getUserStats(UserEntity userEntity){ + if(userEntity.getUserStats() == null || userEntity.getUserStats().size() == 0){ + logger.debug("Stats not found for " + userEntity.getName()); + User user = MainBot.jda.getUserById(userEntity.getJdaId()); + if(user == null) + return null; + List stats = new ArrayList<>(); + for(Guild guid : user.getMutualGuilds()){ + stats.add(new UserStats(guid.getId(), userEntity)); + } + stats = (List) userStatsRepository.save(stats); + userEntity.setUserStats(stats); + userEntity = userRepository.save(userEntity); + + } + return userEntity.getUserStats(); + } + + public List getUserStats(String token) throws UnknownTokenException { + UserEntity user = UserUtils.getInstance().getUserWithApiToken(userRepository, token); + return getUserStats(user); + } + + public List getUserStats(User user){ + UserEntity userEntity; + List userList = userRepository.findByJdaId(user.getId()); + if(userList.size() == 0){ + logger.debug("User not registered, generate it. User: " + user.getName() + " "+ user.getDiscriminator()); + userEntity = genUserEntity(user); + } + else + userEntity = userList.get(0); + + return getUserStats(userEntity); + + } + + public void addMessageCount(Member member){ + List userEntityList = userRepository.findByJdaId(member.getUser().getId()); + UserEntity userEntity; + if( userEntityList.size() == 0) + userEntity = genUserEntity(member.getUser()); + else + userEntity = userEntityList.get(0); + + List userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, member.getGuild().getId()); + if(userStatsList.size() == 0){ + getUserStats(userEntity); + userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, member.getGuild().getId()); + } + UserStats userStats = userStatsList.get(0); + userStats.setMessageCount(userStats.getMessageCount() + 1); + userStatsRepository.save(userStats); + + + } + + public void addApiCount(UserEntity userEntity, String guildId){ + + + List userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, guildId); + if(userStatsList.size() == 0){ + getUserStats(userEntity); + userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, guildId); + } + UserStats userStats = userStatsList.get(0); + userStats.setApiCommandCount(userStats.getApiCommandCount() + 1); + userStatsRepository.save(userStats); + + + } + + + private void addVocalCount(Member member){ + List userEntityList = userRepository.findByJdaId(member.getUser().getId()); + UserEntity userEntity; + if( userEntityList.size() == 0) + userEntity = genUserEntity(member.getUser()); + else + userEntity = userEntityList.get(0); + + List userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, member.getGuild().getId()); + if(userStatsList.size() == 0){ + getUserStats(userEntity); + userStatsList = userStatsRepository.findByUserAndGuildId(userEntity, member.getGuild().getId()); + } + UserStats userStats = userStatsList.get(0); + userStats.setVocalTime(userStats.getVocalTime() + 10); + userStatsRepository.save(userStats); + + + } + + + + + private UserEntity genUserEntity(User user){ + UserEntity userEntity = new UserEntity(user, passwordEncoder); + return userRepository.save(userEntity); + } + + + + public static class VoicePresenceCompter extends Thread{ + private Member member; + public VoicePresenceCompter(Member member){ + this.member = member; + } + + @Override + public void run() { + while (member.getVoiceState().inVoiceChannel()){ + try { + Thread.sleep(10000); + if(member.getVoiceState().inVoiceChannel()) + if(member.getGuild().getAfkChannel() != member.getVoiceState().getChannel()) + UserStatsUtils.getINSTANCE().addVocalCount(member); + + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } +}