Skip to content

Instantly share code, notes, and snippets.

@4drian3d
Created October 15, 2023 14:07
Show Gist options
  • Save 4drian3d/b6e1641d23572f5778be71c3e128a47e to your computer and use it in GitHub Desktop.
Save 4drian3d/b6e1641d23572f5778be71c3e128a47e to your computer and use it in GitHub Desktop.
ChatRegulator Platform Implementation
private static final Check[] CHECKS = {
RegexCheck.builder()
.blockedPatterns(
Stream.of(
"f[uv4@]ck",
"sh[i@lj1y]t",
"d[i@lj1y]c(k)?",
"b[i@lj1y]tch",
"[a@4x]w[3@ex]b[o@0x8]n[a@4x]d[o@0x8]",
"p[u@v]ssy",
"[i@lj1y]mb[3@ex]c[i@lj1y]l",
"m[o@0x8]th[3@ex]rf[u@v]ck[3@ex]r"
).map(pattern -> Pattern.compile(pattern, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)).toList()
).controlType(ControlType.BLOCK).build(),
FloodCheck.builder().limit(10).controlType(ControlType.BLOCK).build(),
SpamCheck.builder().similarLimit(5).source(SourceType.CHAT).build(),
CooldownCheck.builder().limit(350).timeUnit(TimeUnit.MILLISECONDS).source(SourceType.CHAT).build(),
CapsCheck.builder().limit(25).controlType(ControlType.BLOCK).algorithm(CapsAlgorithm.AMOUNT).build()
};
private final ServerDBot plugin;
public ChatListener(ServerDBot plugin) {
this.plugin = plugin;
}
@Override
public Mono<Void> handle(final MessageCreateEvent event) {
return Mono.justOrEmpty(event.getMember())
.map(plugin.infractionManager()::get)
.flatMap(player -> {
final Message message = event.getMessage();
final String messageString = message.getContent();
final CheckResult result = detect(player, messageString);
if (result.isDenied()) {
logDetection(result, player, messageString);
return event.getMessage().delete();
}
player.getChain(SourceType.CHAT).executed(messageString);
return Mono.empty();
});
}
@Override
public Class<MessageCreateEvent> eventClass() {
return MessageCreateEvent.class;
}
private CheckResult detect(InfractionPlayerImpl player, String string) {
for (final Check check : CHECKS) {
final CheckResult result = check.check(player, string);
if (result.isDenied()) {
return result;
}
}
return CheckResult.allowed();
}
private void logDetection(CheckResult result, InfractionPlayer player, String string) {
CheckResult.DeniedCheckResult deniedResult = (CheckResult.DeniedCheckResult) result;
plugin.logger().info("Infraction Detected | Player {} | Infraction {} | String {}", player.username(), deniedResult.infractionType(), string);
}
public class InfractionPlayerImpl implements InfractionPlayer {
private final StringChainImpl stringChain = new StringChainImpl();
private final InfractionCount count = new InfractionCount();
private final Member member;
public InfractionPlayerImpl(Member member) {
this.member = member;
}
@Override
public @NotNull String username() {
return member.getUsername();
}
@Override
public boolean isOnline() {
return true;
}
@Override
public @NotNull StringChainImpl getChain(@NotNull SourceType sourceType) {
return stringChain;
}
@Override
public @NotNull InfractionCount getInfractions() {
return count;
}
@Override
public @NotNull Audience audience() {
return Audience.empty();
}
@Override
public void sendMessage(@NotNull Component message) {
}
}
public final class StringChainImpl implements StringChain {
private final LinkedList<String> queue = new LinkedList<>();
private final AtomicReference<Instant> lastExecuted = new AtomicReference<>(Instant.now().minusMillis(1_000));
@Override
public @NotNull String index(int index) {
return queue.get(index);
}
@Override
public @NotNull String first() {
return queue.getFirst();
}
@Override
public @NotNull String last() {
return queue.getLast();
}
@Override
public @NotNull Instant lastExecuted() {
return lastExecuted.get();
}
@Override
public int size() {
return queue.size();
}
@NotNull
@Override
public Iterator<String> iterator() {
return queue.iterator();
}
public void executed(final String string) {
final int similarCount = 5;
final int size = queue.size();
if (similarCount < size) {
while (similarCount < queue.size() + 1) {
queue.removeFirst();
}
} else if (similarCount == size) {
queue.removeFirst();
}
queue.add(string);
lastExecuted.set(Instant.now());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment