Skip to content

Commit 5f119d5

Browse files
MoonTM-GITDynxstydanthe1st
authored
Added name check and change system (#280)
* Fix MessageCacheListener when direct message is received * Added name check and change system * Fixed Checkstyle * Made Dynxsty's Changes * Made other changes * Made requested changes Co-Authored-By: Dynxsty <dynxsty@javadiscord.net> Co-Authored-By: dan1st <34687786+danthe1st@users.noreply.github.com> * Re-added canBypassCheck * Use Scanner for readStrings * Fix checkstyle Co-authored-by: Dynxsty <dynxsty@javadiscord.net> Co-authored-by: dan1st <34687786+danthe1st@users.noreply.github.com>
1 parent 2c82dd6 commit 5f119d5

File tree

4 files changed

+142
-2
lines changed

4 files changed

+142
-2
lines changed

src/main/java/net/javadiscord/javabot/Bot.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ private static void addEventListeners(JDA jda) {
141141
new InteractionListener(),
142142
new HelpChannelListener(),
143143
new ShareKnowledgeVoteListener(),
144-
new JobChannelVoteListener()
144+
new JobChannelVoteListener(),
145+
new PingableNameListener()
145146
);
146147
}
147148
}

src/main/java/net/javadiscord/javabot/data/h2db/message_cache/MessageCacheListener.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ public void onMessageDelete(@NotNull MessageDeleteEvent event) {
6767
* @return true if any of the criteria above apply
6868
*/
6969
private boolean ignoreMessageCache(Message message) {
70+
if (!message.isFromGuild()) return true;
7071
MessageCacheConfig config = Bot.config.get(message.getGuild()).getMessageCache();
71-
return !message.isFromGuild() || message.getAuthor().isBot() || message.getAuthor().isSystem() ||
72+
return message.getAuthor().isBot() || message.getAuthor().isSystem() ||
7273
config.getExcludedUsers().contains(message.getAuthor().getIdLong()) ||
7374
config.getExcludedChannels().contains(message.getChannel().getIdLong());
7475
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package net.javadiscord.javabot.listener;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import net.dv8tion.jda.api.entities.Member;
5+
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
6+
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
7+
import net.dv8tion.jda.api.hooks.ListenerAdapter;
8+
import net.javadiscord.javabot.systems.notification.GuildNotificationService;
9+
import net.javadiscord.javabot.util.StringUtils;
10+
11+
import java.io.IOException;
12+
import java.net.URL;
13+
import java.util.*;
14+
import java.util.stream.Collectors;
15+
16+
/**
17+
* Checks User's names & nicknames and makes sure they're pingable.
18+
*/
19+
@Slf4j
20+
public class PingableNameListener extends ListenerAdapter {
21+
22+
private static final String ADJECTIVES_URL = "https://gist.githubusercontent.com/karlbright/f91229b8c5ac6f4291dc/raw/4a69c2c50b88ee4559b021c443fee899535adc60/adjectives.txt";
23+
private static final String NOUNS_URL = "https://raw.githubusercontent.com/hugsy/stuff/main/random-word/english-nouns.txt";
24+
private static final Random random = new Random();
25+
private final List<String> nouns;
26+
private final List<String> adjectives;
27+
28+
/**
29+
* Constructs a new PingableNameListener and loads nouns & adjectives.
30+
*/
31+
public PingableNameListener() {
32+
nouns = readStrings(NOUNS_URL);
33+
adjectives = readStrings(ADJECTIVES_URL);
34+
log.info("Loaded {} Nouns!", nouns.size());
35+
log.info("Loaded {} Adjectives!", adjectives.size());
36+
}
37+
38+
@Override
39+
public void onGuildMemberJoin(GuildMemberJoinEvent event) {
40+
checkNickname(event.getMember(), null);
41+
}
42+
43+
@Override
44+
public void onGuildMemberUpdateNickname(GuildMemberUpdateNicknameEvent event) {
45+
checkNickname(event.getMember(), event.getNewNickname());
46+
}
47+
48+
/**
49+
* Checks whether the given {@link Member}'s nickname should be changed.
50+
* @param member The {@link Member} to check.
51+
* @param nickname The {@link Member}'s new Nickname, null if that does not exist.
52+
*/
53+
private void checkNickname(Member member, String nickname) {
54+
if (!(nickname==null||isPingable(nickname)) && !isPingable(member.getUser().getName()) && !canBypassCheck(member)) {
55+
changeName(member);
56+
}
57+
}
58+
59+
/**
60+
* Changes the given {@link Member}s name to a randomly generated one.
61+
* @param member The Member whose name should be changed.
62+
*/
63+
private void changeName(Member member) {
64+
String oldName = member.getNickname();
65+
String newName = generateRandomName();
66+
member.modifyNickname(newName.substring(0, Math.min(31, newName.length()))).queue();
67+
member.getUser().openPrivateChannel()
68+
.flatMap(channel -> channel.sendMessageFormat("Your nickname has been set to `%s` since both your user- and nickname's first three characters were deemed as not-pingable.", newName))
69+
.queue();
70+
new GuildNotificationService(member.getGuild()).sendLogChannelNotification("Changed %s's nickname from `%s` to `%s`.", member.getAsMention(), oldName, newName);
71+
}
72+
73+
/**
74+
* Checks if the given name's first three characters contain ASCII characters not between 32 and 126.
75+
* @param name The name to check.
76+
* @return True if first three characters contain invalid characters, False if not.
77+
*/
78+
private boolean isPingable(String name) {
79+
if (name == null) return true;
80+
char[] nameChars = name.toCharArray();
81+
for (int i = 0; i < Math.min(2,name.length()); i++) {
82+
char c = nameChars[i];
83+
if (c < 32 || c > 126) {
84+
return false;
85+
}
86+
}
87+
return true;
88+
}
89+
90+
/**
91+
* Generates a random name consisting of a noun, an adjective and a number from 1 to 9999.
92+
* @return The generated name.
93+
*/
94+
private String generateRandomName() {
95+
String noun = nouns.get(random.nextInt(nouns.size()));
96+
String adjective = adjectives.get(random.nextInt(adjectives.size()));
97+
int number = random.nextInt(10000);
98+
return StringUtils.capitalize(adjective) + StringUtils.capitalize(noun) + number;
99+
}
100+
101+
/**
102+
* Reads strings from the given URL to a {@link List}, removes words with a dash.
103+
* @param url The URL to read.
104+
* @return A {@link List} of Strings.
105+
*/
106+
private static List<String> readStrings(String url) {
107+
List<String> list;
108+
try (Scanner scan = new Scanner(new URL(url).openStream()).useDelimiter("\\n")) {
109+
list = scan.tokens().collect(Collectors.toList());
110+
} catch (IOException e) {
111+
log.error("Error during retrieval of words.");
112+
list = new ArrayList<>();
113+
}
114+
115+
list.removeIf(word -> word.contains("-"));
116+
return list;
117+
}
118+
119+
/**
120+
* Checks if the given {@link Member} can bypass the name-check.
121+
* @param member The {@link Member} to check.
122+
* @return Whether the Member can bypass name-checks or not.
123+
*/
124+
private static boolean canBypassCheck(Member member) {
125+
return member.getUser().isBot() || member.getUser().isSystem() || member.getGuild().getSelfMember().canInteract(member);
126+
}
127+
}

src/main/java/net/javadiscord/javabot/util/StringUtils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,15 @@ public static String buildProgressBar(double current, double max, String off, St
7070
int onLength = (int) (length * percent);
7171
return on.repeat(onLength) + off.repeat(length - onLength);
7272
}
73+
74+
/**
75+
* Capitalizes the given word.
76+
*
77+
* @param word The word to capitalize.
78+
* @return The capitalized word.
79+
*/
80+
public static String capitalize(String word) {
81+
if (word == null || word.isEmpty()) return word;
82+
return word.substring(0, 1).toUpperCase() + word.substring(1);
83+
}
7384
}

0 commit comments

Comments
 (0)