Refactor chat message handling. It now supports sending chat messages with just a UUID and a string message. (For support for web messages)
This commit is contained in:
parent
9143642761
commit
6db9816c85
|
|
@ -1,5 +1,6 @@
|
||||||
package com.alttd.chat;
|
package com.alttd.chat;
|
||||||
|
|
||||||
|
import com.alttd.chat.chat_web.ChatMessageSender;
|
||||||
import com.alttd.chat.commands.*;
|
import com.alttd.chat.commands.*;
|
||||||
import com.alttd.chat.config.Config;
|
import com.alttd.chat.config.Config;
|
||||||
import com.alttd.chat.config.ServerConfig;
|
import com.alttd.chat.config.ServerConfig;
|
||||||
|
|
@ -39,8 +40,9 @@ public class ChatPlugin extends JavaPlugin {
|
||||||
chatHandler = new ChatHandler(chatLogHandler);
|
chatHandler = new ChatHandler(chatLogHandler);
|
||||||
DatabaseConnection.initialize();
|
DatabaseConnection.initialize();
|
||||||
serverConfig = new ServerConfig(ServerName.getServerName());
|
serverConfig = new ServerConfig(ServerName.getServerName());
|
||||||
|
ChatMessageSender chatMessageSender = new ChatMessageSender(chatLogHandler, chatAPI.getLuckPerms());
|
||||||
registerListener(new PlayerListener(serverConfig),
|
registerListener(new PlayerListener(serverConfig),
|
||||||
new ChatListener(chatLogHandler),
|
new ChatListener(chatMessageSender),
|
||||||
new BookListener(),
|
new BookListener(),
|
||||||
new ShutdownListener(chatLogHandler, this)
|
new ShutdownListener(chatLogHandler, this)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,278 @@
|
||||||
|
package com.alttd.chat.chat_web;
|
||||||
|
|
||||||
|
import com.alttd.chat.ChatPlugin;
|
||||||
|
import com.alttd.chat.config.Config;
|
||||||
|
import com.alttd.chat.managers.ChatUserManager;
|
||||||
|
import com.alttd.chat.managers.RegexManager;
|
||||||
|
import com.alttd.chat.objects.ChatUser;
|
||||||
|
import com.alttd.chat.objects.FilterType;
|
||||||
|
import com.alttd.chat.objects.ModifiableString;
|
||||||
|
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
||||||
|
import com.alttd.chat.objects.chat_log.ChatLogType;
|
||||||
|
import com.alttd.chat.util.ALogger;
|
||||||
|
import com.alttd.chat.util.GalaxyUtility;
|
||||||
|
import com.alttd.chat.util.ServerName;
|
||||||
|
import com.alttd.chat.util.Utility;
|
||||||
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
|
import net.kyori.adventure.text.TextReplacementConfig;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
import net.luckperms.api.LuckPerms;
|
||||||
|
import net.luckperms.api.context.ImmutableContextSet;
|
||||||
|
import net.luckperms.api.model.user.User;
|
||||||
|
import net.luckperms.api.query.QueryOptions;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ChatMessageSender {
|
||||||
|
|
||||||
|
private final ChatLogHandler chatLogHandler;
|
||||||
|
private final LuckPerms luckPerms;
|
||||||
|
private final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
|
|
||||||
|
public void sendMessage(UUID sender, String message) {
|
||||||
|
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(sender);
|
||||||
|
Component component = miniMessage.deserialize(message);
|
||||||
|
sendMessage(offlinePlayer, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(@NotNull OfflinePlayer offlinePlayer, Component message) {
|
||||||
|
UUID uuid = offlinePlayer.getUniqueId();
|
||||||
|
if (luckPerms.getUserManager().isLoaded(uuid)) {
|
||||||
|
User user = luckPerms.getUserManager().getUser(uuid);
|
||||||
|
sendMessage(user, offlinePlayer, message);
|
||||||
|
} else {
|
||||||
|
luckPerms.getUserManager().loadUser(uuid).whenComplete((user, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
ALogger.error("Failed to load user: " + uuid, throwable);
|
||||||
|
}
|
||||||
|
sendMessage(user, offlinePlayer, message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(User user, OfflinePlayer offlinePlayer, Component message) {
|
||||||
|
if (offlinePlayer == null) {
|
||||||
|
ALogger.error("OfflinePlayer is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ChatPlugin.getInstance().serverMuted() && !hasPermission(user, "chat.bypass-server-muted")) {
|
||||||
|
sendBlockNotifIfOnline(offlinePlayer, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID uuid = offlinePlayer.getUniqueId();
|
||||||
|
|
||||||
|
ComponentLike input = message.colorIfAbsent(NamedTextColor.WHITE);
|
||||||
|
Component inputComponent = input.asComponent();
|
||||||
|
|
||||||
|
ModifiableString modifiableString = new ModifiableString(inputComponent);
|
||||||
|
|
||||||
|
if (parseMessage(offlinePlayer, uuid, modifiableString, inputComponent)) {
|
||||||
|
//Parse message failed likely due to something the player said, already logged
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendMessageAndPing(user, offlinePlayer, uuid, modifiableString)) {
|
||||||
|
//Send message and ping failed, likely due to the offlinePlayer not being valid, already logged
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ALogger.info(PlainTextComponentSerializer.plainText().serialize(inputComponent));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean sendMessageAndPing(User user, OfflinePlayer offlinePlayer, UUID uuid, ModifiableString modifiableString) {
|
||||||
|
ComponentLike input;
|
||||||
|
Stream<Player> stream = Bukkit.getOnlinePlayers().stream()
|
||||||
|
.map(audience -> (Player) audience);
|
||||||
|
|
||||||
|
if (!hasPermission(user, "chat.ignorebypass")) {
|
||||||
|
stream = stream.filter(receiver -> {
|
||||||
|
boolean isPlayerIgnored = ChatUserManager
|
||||||
|
.getChatUser(receiver.getUniqueId())
|
||||||
|
.getIgnoredPlayers()
|
||||||
|
.contains(uuid);
|
||||||
|
return !isPlayerIgnored || receiver.hasPermission("chat.ignorebypass");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Set<Player> receivers = stream.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Set<Player> playersToPing = new HashSet<>();
|
||||||
|
pingPlayers(playersToPing, modifiableString, offlinePlayer, user);
|
||||||
|
|
||||||
|
Optional<ComponentLike> render = render(offlinePlayer, modifiableString.component());
|
||||||
|
if (render.isEmpty()) {
|
||||||
|
//Already logged
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
input = render.get();
|
||||||
|
for (Player receiver : receivers) {
|
||||||
|
receiver.sendMessage(input);
|
||||||
|
}
|
||||||
|
for (Player pingPlayer : playersToPing) {
|
||||||
|
pingPlayer.playSound(pingPlayer.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 1);
|
||||||
|
}
|
||||||
|
chatLogHandler.addChatLog(uuid,
|
||||||
|
ServerName.getServerName(),
|
||||||
|
modifiableString.string(),
|
||||||
|
ChatLogType.PUBLIC,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
input.asComponent(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean parseMessage(OfflinePlayer offlinePlayer, UUID uuid, ModifiableString modifiableString, Component inputComponent) {
|
||||||
|
// todo a better way for this
|
||||||
|
if (!RegexManager.filterText(offlinePlayer.getName(), uuid, modifiableString, true, "chat",
|
||||||
|
filterType -> punishOnlinePlayer(filterType, uuid, modifiableString)
|
||||||
|
)) {
|
||||||
|
GalaxyUtility.sendBlockedNotification("Language", offlinePlayer,
|
||||||
|
modifiableString.component(),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
String originalMessage = PlainTextComponentSerializer.plainText().serialize(inputComponent);
|
||||||
|
Optional<Component> component = render(offlinePlayer, inputComponent).map(ComponentLike::asComponent);
|
||||||
|
if (component.isEmpty()) {
|
||||||
|
//Already logged
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
chatLogHandler.addChatLog(uuid,
|
||||||
|
ServerName.getServerName(),
|
||||||
|
originalMessage,
|
||||||
|
ChatLogType.PUBLIC,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
component.get(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pingPlayers(Set<Player> playersToPing, ModifiableString modifiableString, OfflinePlayer offlinePlayer, User user) {
|
||||||
|
Component mention = MiniMessage.miniMessage().deserialize(Config.MENTIONPLAYERTAG);
|
||||||
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
|
String name = onlinePlayer.getName();
|
||||||
|
String nickName = PlainTextComponentSerializer.plainText().serialize(onlinePlayer.displayName());
|
||||||
|
|
||||||
|
Pattern namePattern = Pattern.compile("\\b(?<!\\\\)" + name + "\\b", Pattern.CASE_INSENSITIVE);
|
||||||
|
// Pattern escapedNamePattern = Pattern.compile("\\b\\\\" + name + "\\b", Pattern.CASE_INSENSITIVE);
|
||||||
|
Pattern nickPattern = Pattern.compile("\\b(?<!\\\\)" + nickName + "\\b", Pattern.CASE_INSENSITIVE);
|
||||||
|
// Pattern escapedNickPattern = Pattern.compile("\\b\\\\" + nickName + "\\b", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
ChatUser onlinePlayerUser = ChatUserManager.getChatUser(onlinePlayer.getUniqueId());
|
||||||
|
if (namePattern.matcher(modifiableString.string()).find()) {
|
||||||
|
modifiableString.replace(TextReplacementConfig.builder()
|
||||||
|
.once()
|
||||||
|
.match(namePattern)
|
||||||
|
.replacement(mention.append(onlinePlayerUser.getDisplayName()))
|
||||||
|
.build());
|
||||||
|
//TODO replace all instances of \name with just name but using the match result so the capitalization doesn't change
|
||||||
|
// modifiableString.replace(TextReplacementConfig.builder()
|
||||||
|
// .once()
|
||||||
|
// .match(escapedNamePattern)
|
||||||
|
// .replacement((a, b) -> {
|
||||||
|
// String substring = a.group().substring(1);
|
||||||
|
// return ;
|
||||||
|
// });
|
||||||
|
|
||||||
|
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId())
|
||||||
|
.getIgnoredPlayers()
|
||||||
|
.contains(offlinePlayer.getUniqueId())
|
||||||
|
|| hasPermission(user, "chat.ignorebypass")) {
|
||||||
|
playersToPing.add(onlinePlayer);
|
||||||
|
}
|
||||||
|
} else if (nickPattern.matcher(modifiableString.string()).find()) {
|
||||||
|
modifiableString.replace(TextReplacementConfig.builder()
|
||||||
|
.once()
|
||||||
|
.match(nickPattern)
|
||||||
|
.replacement(mention.append(onlinePlayerUser.getDisplayName()))
|
||||||
|
.build());
|
||||||
|
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId())
|
||||||
|
.getIgnoredPlayers()
|
||||||
|
.contains(offlinePlayer.getUniqueId())
|
||||||
|
|| hasPermission(user, "chat.ignorebypass")) {
|
||||||
|
playersToPing.add(onlinePlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ComponentLike> render(@NotNull OfflinePlayer offlinePlayer, @NotNull Component message) {
|
||||||
|
if (offlinePlayer.getName() == null) {
|
||||||
|
ALogger.error("Invalid offline player");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatUser user = ChatUserManager.getChatUser(offlinePlayer.getUniqueId());
|
||||||
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
|
Placeholder.component("sender", user.getDisplayName()),
|
||||||
|
Placeholder.parsed("sendername", offlinePlayer.getName()),
|
||||||
|
Placeholder.component("prefix", user.getPrefix()),
|
||||||
|
Placeholder.component("prefixall", user.getPrefixAll()),
|
||||||
|
Placeholder.component("staffprefix", user.getStaffPrefix()),
|
||||||
|
Placeholder.component("message", message)
|
||||||
|
);
|
||||||
|
|
||||||
|
return Optional.of(Utility.parseMiniMessage(Config.CHATFORMAT, placeholders));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void punishOnlinePlayer(FilterType filterType, UUID uuid, ModifiableString modifiableString) {
|
||||||
|
Player player = Bukkit.getPlayer(uuid);
|
||||||
|
if (player == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!filterType.equals(FilterType.PUNISH)) {
|
||||||
|
ALogger.warn("Received another FilterType than punish when filtering chat and executing a filter action");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||||
|
out.writeUTF("punish");
|
||||||
|
out.writeUTF(player.getName());
|
||||||
|
out.writeUTF(uuid.toString());
|
||||||
|
out.writeUTF(modifiableString.string());
|
||||||
|
player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sendBlockNotifIfOnline(OfflinePlayer offlinePlayer, Component message) {
|
||||||
|
if (!offlinePlayer.isOnline()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player player = offlinePlayer.getPlayer();
|
||||||
|
if (player == null) {
|
||||||
|
ALogger.error("Failed to load player: " + offlinePlayer.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GalaxyUtility.sendBlockedNotification("Chat Muted", player, message, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPermission(User user, String permission) {
|
||||||
|
return user.getCachedData()
|
||||||
|
.getPermissionData(QueryOptions.contextual(ImmutableContextSet.of("server", luckPerms.getServerName())))
|
||||||
|
.checkPermission(permission)
|
||||||
|
.asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,53 +1,32 @@
|
||||||
package com.alttd.chat.listeners;
|
package com.alttd.chat.listeners;
|
||||||
|
|
||||||
import com.alttd.chat.ChatPlugin;
|
import com.alttd.chat.chat_web.ChatMessageSender;
|
||||||
import com.alttd.chat.config.Config;
|
import com.alttd.chat.config.Config;
|
||||||
import com.alttd.chat.handler.ChatHandler;
|
import com.alttd.chat.handler.ChatHandler;
|
||||||
import com.alttd.chat.managers.ChatUserManager;
|
|
||||||
import com.alttd.chat.managers.RegexManager;
|
import com.alttd.chat.managers.RegexManager;
|
||||||
import com.alttd.chat.objects.*;
|
import com.alttd.chat.objects.ChatFilter;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
import com.alttd.chat.objects.Toggleable;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogType;
|
|
||||||
import com.alttd.chat.util.ALogger;
|
|
||||||
import com.alttd.chat.util.GalaxyUtility;
|
|
||||||
import com.alttd.chat.util.ServerName;
|
|
||||||
import com.alttd.chat.util.Utility;
|
import com.alttd.chat.util.Utility;
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent;
|
import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent;
|
||||||
import io.papermc.paper.event.player.AsyncChatDecorateEvent;
|
import io.papermc.paper.event.player.AsyncChatDecorateEvent;
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.ComponentLike;
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
import net.kyori.adventure.text.TextReplacementConfig;
|
import net.kyori.adventure.text.TextReplacementConfig;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ChatListener implements Listener {
|
public class ChatListener implements Listener {
|
||||||
|
|
||||||
private final PlainTextComponentSerializer plainTextComponentSerializer = PlainTextComponentSerializer.plainText();
|
private final PlainTextComponentSerializer plainTextComponentSerializer = PlainTextComponentSerializer.plainText();
|
||||||
private final ChatLogHandler chatLogHandler;
|
private final ChatMessageSender chatMessageSender;
|
||||||
|
|
||||||
public ChatListener(ChatLogHandler chatLogHandler) {
|
|
||||||
this.chatLogHandler = chatLogHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onChatCommandDecorate(AsyncChatCommandDecorateEvent event) {
|
public void onChatCommandDecorate(AsyncChatCommandDecorateEvent event) {
|
||||||
|
|
@ -83,8 +62,6 @@ public class ChatListener implements Listener {
|
||||||
.build()));
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Component mention = MiniMessage.miniMessage().deserialize(Config.MENTIONPLAYERTAG);
|
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onPlayerChat(AsyncChatEvent event) {
|
public void onPlayerChat(AsyncChatEvent event) {
|
||||||
event.setCancelled(true); //Always cancel the event because we do not want to deal with Microsoft's stupid bans
|
event.setCancelled(true); //Always cancel the event because we do not want to deal with Microsoft's stupid bans
|
||||||
|
|
@ -93,148 +70,7 @@ public class ChatListener implements Listener {
|
||||||
toggleable.sendMessage(event.getPlayer(), event.message());
|
toggleable.sendMessage(event.getPlayer(), event.message());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ChatPlugin.getInstance().serverMuted() && !event.getPlayer().hasPermission("chat.bypass-server-muted")) {
|
chatMessageSender.sendMessage(event.getPlayer(), event.message());
|
||||||
Player player = event.getPlayer();
|
|
||||||
GalaxyUtility.sendBlockedNotification("Chat Muted", player, event.message(), "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
UUID uuid = player.getUniqueId();
|
|
||||||
|
|
||||||
ComponentLike input = event.message().colorIfAbsent(NamedTextColor.WHITE);
|
|
||||||
Component inputComponent = input.asComponent();
|
|
||||||
|
|
||||||
ModifiableString modifiableString = new ModifiableString(inputComponent);
|
|
||||||
|
|
||||||
// todo a better way for this
|
|
||||||
if (!RegexManager.filterText(player.getName(), uuid, modifiableString, true, "chat", filterType -> {
|
|
||||||
if (!filterType.equals(FilterType.PUNISH)) {
|
|
||||||
ALogger.warn("Received another FilterType than punish when filtering chat and executing a filter action");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
|
||||||
out.writeUTF("punish");
|
|
||||||
out.writeUTF(player.getName());
|
|
||||||
out.writeUTF(uuid.toString());
|
|
||||||
out.writeUTF(modifiableString.string());
|
|
||||||
player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray());
|
|
||||||
}
|
|
||||||
)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
GalaxyUtility.sendBlockedNotification("Language", player,
|
|
||||||
modifiableString.component(),
|
|
||||||
""
|
|
||||||
);
|
|
||||||
String originalMessage = PlainTextComponentSerializer.plainText().serialize(inputComponent);
|
|
||||||
chatLogHandler.addChatLog(uuid,
|
|
||||||
ServerName.getServerName(),
|
|
||||||
originalMessage,
|
|
||||||
ChatLogType.PUBLIC,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
render(player, inputComponent).asComponent(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
return; // the message was blocked
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<Player> stream = event.viewers().stream().filter(audience -> audience instanceof Player)
|
|
||||||
.map(audience -> (Player) audience);
|
|
||||||
|
|
||||||
if (!player.hasPermission("chat.ignorebypass")) {
|
|
||||||
stream = stream.filter(receiver -> {
|
|
||||||
boolean isPlayerIgnored = ChatUserManager
|
|
||||||
.getChatUser(receiver.getUniqueId())
|
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(uuid);
|
|
||||||
return !isPlayerIgnored || receiver.hasPermission("chat.ignorebypass");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Set<Player> receivers = stream.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
Set<Player> playersToPing = new HashSet<>();
|
|
||||||
pingPlayers(playersToPing, modifiableString, player);
|
|
||||||
|
|
||||||
input = render(player, modifiableString.component());
|
|
||||||
for (Player receiver : receivers) {
|
|
||||||
receiver.sendMessage(input);
|
|
||||||
}
|
|
||||||
for (Player pingPlayer : playersToPing) {
|
|
||||||
pingPlayer.playSound(pingPlayer.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 1);
|
|
||||||
}
|
|
||||||
chatLogHandler.addChatLog(uuid,
|
|
||||||
ServerName.getServerName(),
|
|
||||||
modifiableString.string(),
|
|
||||||
ChatLogType.PUBLIC,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
input.asComponent(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
ALogger.info(PlainTextComponentSerializer.plainText().serialize(inputComponent));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pingPlayers(Set<Player> playersToPing, ModifiableString modifiableString, Player player) {
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
|
||||||
String name = onlinePlayer.getName();
|
|
||||||
String nickName = PlainTextComponentSerializer.plainText().serialize(onlinePlayer.displayName());
|
|
||||||
|
|
||||||
Pattern namePattern = Pattern.compile("\\b(?<!\\\\)" + name + "\\b", Pattern.CASE_INSENSITIVE);
|
|
||||||
// Pattern escapedNamePattern = Pattern.compile("\\b\\\\" + name + "\\b", Pattern.CASE_INSENSITIVE);
|
|
||||||
Pattern nickPattern = Pattern.compile("\\b(?<!\\\\)" + nickName + "\\b", Pattern.CASE_INSENSITIVE);
|
|
||||||
// Pattern escapedNickPattern = Pattern.compile("\\b\\\\" + nickName + "\\b", Pattern.CASE_INSENSITIVE);
|
|
||||||
|
|
||||||
ChatUser onlinePlayerUser = ChatUserManager.getChatUser(onlinePlayer.getUniqueId());
|
|
||||||
if (namePattern.matcher(modifiableString.string()).find()) {
|
|
||||||
modifiableString.replace(TextReplacementConfig.builder()
|
|
||||||
.once()
|
|
||||||
.match(namePattern)
|
|
||||||
.replacement(mention.append(onlinePlayerUser.getDisplayName()))
|
|
||||||
.build());
|
|
||||||
//TODO replace all instances of \name with just name but using the match result so the capitalization doesn't change
|
|
||||||
// modifiableString.replace(TextReplacementConfig.builder()
|
|
||||||
// .once()
|
|
||||||
// .match(escapedNamePattern)
|
|
||||||
// .replacement((a, b) -> {
|
|
||||||
// String substring = a.group().substring(1);
|
|
||||||
// return ;
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId())
|
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(player.getUniqueId())
|
|
||||||
|| player.hasPermission("chat.ignorebypass")) {
|
|
||||||
playersToPing.add(onlinePlayer);
|
|
||||||
}
|
|
||||||
} else if (nickPattern.matcher(modifiableString.string()).find()) {
|
|
||||||
modifiableString.replace(TextReplacementConfig.builder()
|
|
||||||
.once()
|
|
||||||
.match(nickPattern)
|
|
||||||
.replacement(mention.append(onlinePlayerUser.getDisplayName()))
|
|
||||||
.build());
|
|
||||||
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId())
|
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(player.getUniqueId())
|
|
||||||
|| player.hasPermission("chat.ignorebypass")) {
|
|
||||||
playersToPing.add(onlinePlayer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ComponentLike render(@NotNull Player player, @NotNull Component message) {
|
|
||||||
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
|
|
||||||
TagResolver placeholders = TagResolver.resolver(
|
|
||||||
Placeholder.component("sender", user.getDisplayName()),
|
|
||||||
Placeholder.parsed("sendername", player.getName()),
|
|
||||||
Placeholder.component("prefix", user.getPrefix()),
|
|
||||||
Placeholder.component("prefixall", user.getPrefixAll()),
|
|
||||||
Placeholder.component("staffprefix", user.getStaffPrefix()),
|
|
||||||
Placeholder.component("message", message)
|
|
||||||
);
|
|
||||||
|
|
||||||
return Utility.parseMiniMessage(Config.CHATFORMAT, placeholders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ComponentLike parseMessageContent(Player player, String rawMessage) {
|
private ComponentLike parseMessageContent(Player player, String rawMessage) {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import net.kyori.adventure.text.ComponentLike;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -13,13 +14,14 @@ import java.util.List;
|
||||||
|
|
||||||
public class GalaxyUtility {
|
public class GalaxyUtility {
|
||||||
|
|
||||||
public static void sendBlockedNotification(String prefix, Player player, ComponentLike input, String target) {
|
public static void sendBlockedNotification(String prefix, OfflinePlayer offlinePlayer, ComponentLike input, String target) {
|
||||||
|
String playerName = offlinePlayer.getName() == null ? "unknown_player" : offlinePlayer.getName();
|
||||||
TagResolver placeholders = TagResolver.resolver(
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
Placeholder.parsed("prefix", prefix),
|
Placeholder.parsed("prefix", prefix),
|
||||||
Placeholder.parsed("displayname", Utility.getDisplayName(player.getUniqueId(), player.getName())),
|
Placeholder.parsed("displayname", Utility.getDisplayName(offlinePlayer.getUniqueId(), playerName)),
|
||||||
Placeholder.parsed("target", (target.isEmpty() ? "tried to say:" : "-> " + target + ":")),
|
Placeholder.parsed("target", (target.isEmpty() ? "tried to say:" : "-> " + target + ":")),
|
||||||
Placeholder.component("input", input)
|
Placeholder.component("input", input)
|
||||||
);
|
);
|
||||||
ComponentLike blockedNotification = Utility.parseMiniMessage(Config.NOTIFICATIONFORMAT, placeholders);
|
ComponentLike blockedNotification = Utility.parseMiniMessage(Config.NOTIFICATIONFORMAT, placeholders);
|
||||||
|
|
||||||
Bukkit.getOnlinePlayers().forEach(a -> {
|
Bukkit.getOnlinePlayers().forEach(a -> {
|
||||||
|
|
@ -27,8 +29,15 @@ public class GalaxyUtility {
|
||||||
a.sendMessage(blockedNotification);
|
a.sendMessage(blockedNotification);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
player.sendRichMessage("<red>The language you used in your message is not allowed, " +
|
if (offlinePlayer.isOnline()) {
|
||||||
"this constitutes as your only warning. Any further attempts at bypassing the filter will result in staff intervention.</red>");
|
Player player = offlinePlayer.getPlayer();
|
||||||
|
if (player == null) {
|
||||||
|
ALogger.error("Player is offline but isOnline() returned true");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player.sendRichMessage("<red>The language you used in your message is not allowed, " +
|
||||||
|
"this constitutes as your only warning. Any further attempts at bypassing the filter will result in staff intervention.</red>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addAdditionalChatCompletions(Player player) {
|
public static void addAdditionalChatCompletions(Player player) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user