Skip to content

Commit

Permalink
Merge pull request #1 from yoshiweegee/master
Browse files Browse the repository at this point in the history
Add option "match.blacklist" to remove specific substrings from chat messages
  • Loading branch information
DoggySazHi authored Mar 23, 2024
2 parents 542c31f + 95c0f00 commit 4b60e66
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 78 deletions.
3 changes: 3 additions & 0 deletions src/main/java/net/gensokyoreimagined/motoori/Kosuzu.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -59,6 +60,8 @@ public void onEnable() {

config.addDefault("match.include", regexDefaults);

config.addDefault("match.blacklist", Collections.<String>emptyList());

config.options().copyDefaults(true);
saveConfig();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,26 @@
package net.gensokyoreimagined.motoori;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;

public class KosuzuParsesEverything {
private final ArrayList<Pattern> regexes = new ArrayList<>();
private final Map<String, Map<UUID, Pattern>> placeholderRegexes = new HashMap<>();
private final List<String> syntaxBlacklist;

public KosuzuParsesEverything(Kosuzu kosuzu) {
var logger = kosuzu.getLogger();

var config = kosuzu.config;
var regexes = config.getStringList("match.include");

Expand All @@ -42,7 +47,11 @@ public KosuzuParsesEverything(Kosuzu kosuzu) {
}
}

kosuzu.getLogger().info("Prepared " + this.regexes.size() + " regexes");
logger.info("Prepared " + this.regexes.size() + " regexes");

syntaxBlacklist = config.getStringList("match.blacklist");

logger.info("Added " + syntaxBlacklist.size() + " blacklist entries");
}

/**
Expand Down Expand Up @@ -76,4 +85,40 @@ public KosuzuParsesEverything(Kosuzu kosuzu) {

return null;
}

/**
* Removes unwanted chat syntax from the message, in case someone's trying to be a neerdowell.
* Examples of syntax include chat prefixes and role prefixes.
* @param message The message to modify.
* @return The same message after modification
*/
public Component removeUnwantedSyntax(Component message) {
// only plain text components are of concern for now
if (!(message instanceof TextComponent)) return message;

for (var childComponent : message.children()) {
if (!(childComponent instanceof TextComponent)) return message;
}

var messagePlaintext = (TextComponent) message;
var componentContent = messagePlaintext.content();
boolean matched;
do {
matched = false;
for (var syntaxBlacklistString : syntaxBlacklist) {
matched = matched || componentContent.indexOf(syntaxBlacklistString) != -1;
componentContent = componentContent.replaceAll(syntaxBlacklistString, "");
}
} while (matched);
message = messagePlaintext.content(componentContent);

var currentChildren = message.children();
var newChildren = new ArrayList<Component>(currentChildren.size());
for (var childComponent : currentChildren) {
newChildren.add(removeUnwantedSyntax(childComponent));
}
message.children(newChildren);

return message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,12 @@

package net.gensokyoreimagined.motoori;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import io.papermc.paper.event.player.AsyncChatDecorateEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket;
import net.minecraft.server.MinecraftServer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
Expand All @@ -49,86 +41,36 @@ public KosuzuUnderstandsEverything(Kosuzu kosuzu) {
database = kosuzu.database;
geolocation = new KosuzuKnowsWhereYouLive(kosuzu);
parser = new KosuzuParsesEverything(kosuzu);

ProtocolManager manager = ProtocolLibrary.getProtocolManager();
manager.addPacketListener(new PacketAdapter(kosuzu, ListenerPriority.NORMAL, PacketType.Play.Server.CHAT) {
@Override
public void onPacketSending(PacketEvent event) {
onClientChatSend(event);
}
});

manager.addPacketListener(new PacketAdapter(kosuzu, ListenerPriority.NORMAL, PacketType.Play.Server.SYSTEM_CHAT) {
@Override
public void onPacketSending(PacketEvent event) {
onServerChatSend(event);
}
});
}

private void onClientChatSend(PacketEvent event) {
var player = event.getPlayer();
var packet = event.getPacket();

var signature = (ClientboundPlayerChatPacket) packet.getMessageSignatures().getTarget();
var message = Objects.requireNonNullElseGet(signature.unsignedContent(), () -> net.minecraft.network.chat.Component.literal(signature.body().content()));
@EventHandler(priority = EventPriority.LOWEST)
private void onChatDecorateEarliest(AsyncChatDecorateEvent event) {
var player = event.player();
if (player == null) return;

var boundChatType = signature.chatType().resolve(MinecraftServer.getServer().registryAccess());
// filter early to adjust for following decorators
event.result(parser.removeUnwantedSyntax(event.originalMessage()));
}

if (boundChatType.isEmpty()) {
logger.warning("Don't know how to process packet with unknown ChatType " + signature.chatType().chatType());
return;
}
@EventHandler(priority = EventPriority.HIGHEST)
private void onChatDecorateLatest(AsyncChatDecorateEvent event) {
var player = event.player();
if (player == null) return;

// Use the vanilla decorated content and then convert it to Adventure API
var decoratedContent = boundChatType.orElseThrow().decorate(message);
var text = decoratedContent.getString();
var component = Component.text(text);
// Only to get the JSON
var json = JSONComponentSerializer.json().serialize(component);
// retrieve original filtered message
var message = parser.removeUnwantedSyntax(event.originalMessage());

var uuid = database.addMessage(json, message.getString());
var json = JSONComponentSerializer.json().serialize(event.result());
var uuid = database.addMessage(json, PlainTextComponentSerializer.plainText().serialize(message));

var newComponent = component.hoverEvent(
event.result(event.result().hoverEvent(
Component
.text(database.getTranslation("translate.hover", database.getUserDefaultLanguage(player.getUniqueId())))
.color(NamedTextColor.GRAY)
)
.clickEvent(
ClickEvent.runCommand("/kosuzu translate " + uuid.toString())
);

var newJson = JSONComponentSerializer.json().serialize(newComponent);

packet = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
packet.getChatComponents().write(0, WrappedChatComponent.fromJson(newJson));
event.setPacket(packet);
}

private void onServerChatSend(PacketEvent event) {
var player = event.getPlayer();
var packet = event.getPacket();
var message = packet.getChatComponents().read(0);

var json = message.getJson();
var component = JSONComponentSerializer.json().deserialize(json); // Adventure API from raw JSON
var text = parser.getTextMessage(component, player);

if (text != null) {
var uuid = database.addMessage(json, text);

var newComponent = component.hoverEvent(
Component
.text(database.getTranslation("translate.hover", database.getUserDefaultLanguage(player.getUniqueId())))
.color(NamedTextColor.GRAY)
)
.clickEvent(
ClickEvent.runCommand("/kosuzu translate " + uuid.toString())
);

var newJson = JSONComponentSerializer.json().serialize(newComponent);
packet.getChatComponents().write(0, WrappedChatComponent.fromJson(newJson));
}
));
}

@EventHandler(priority = EventPriority.HIGHEST)
Expand Down

0 comments on commit 4b60e66

Please sign in to comment.