mirror of
https://github.com/EssentialsX/Essentials.git
synced 2025-04-06 13:30:43 +08:00
parent
4e6478224c
commit
cb00783ede
@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.flattener.ComponentFlattener;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
@ -20,6 +21,7 @@ public final class AdventureUtil {
|
||||
static {
|
||||
final LegacyComponentSerializer.Builder builder = LegacyComponentSerializer.builder()
|
||||
.flattener(ComponentFlattener.basic())
|
||||
.extractUrls(AbstractChatEvent.URL_PATTERN)
|
||||
.useUnusualXRepeatedCharacterHexFormat();
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_1_R01)) {
|
||||
builder.hexColors();
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Color;
|
||||
|
||||
@ -24,7 +25,6 @@ public final class FormatUtil {
|
||||
private static final Pattern REPLACE_ALL_RGB_PATTERN = Pattern.compile("(&)?&#([0-9a-fA-F]{6})");
|
||||
//Used to prepare xmpp output
|
||||
private static final Pattern LOGCOLOR_PATTERN = Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]");
|
||||
private static final Pattern URL_PATTERN = Pattern.compile("((?:(?:https?)://)?[\\w-_\\.]{2,})\\.([a-zA-Z]{2,3}(?:/\\S+)?)");
|
||||
//Used to strip ANSI control codes from console
|
||||
private static final Pattern ANSI_CONTROL_PATTERN = Pattern.compile("[\\x1B\\x9B][\\[\\]()#;?]*(?:(?:(?:;[-a-zA-Z\\d/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d/#&.:=?%@~_]*)*)?\\x07|(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~])");
|
||||
private static final Pattern PAPER_CONTROL_PATTERN = Pattern.compile("(?i)" + (char) 0x7f + "[0-9A-FK-ORX]");
|
||||
@ -297,9 +297,9 @@ public final class FormatUtil {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
String text = URL_PATTERN.matcher(input).replaceAll("$1 $2");
|
||||
while (URL_PATTERN.matcher(text).find()) {
|
||||
text = URL_PATTERN.matcher(text).replaceAll("$1 $2");
|
||||
String text = AbstractChatEvent.URL_PATTERN.matcher(input).replaceAll("$1 $2");
|
||||
while (AbstractChatEvent.URL_PATTERN.matcher(text).find()) {
|
||||
text = AbstractChatEvent.URL_PATTERN.matcher(text).replaceAll("$1 $2");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package com.earth2me.essentials.chat;
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.EssentialsLogger;
|
||||
import com.earth2me.essentials.chat.processing.ChatHandler;
|
||||
import com.earth2me.essentials.chat.processing.PaperChatHandler;
|
||||
import com.earth2me.essentials.metrics.MetricsWrapper;
|
||||
import com.earth2me.essentials.utils.AdventureUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -32,8 +34,13 @@ public class EssentialsChat extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
final ChatHandler legacyHandler = new ChatHandler((Essentials) ess, this);
|
||||
legacyHandler.registerListeners();
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_5_R01) && VersionUtil.isPaper()) {
|
||||
final PaperChatHandler paperHandler = new PaperChatHandler((Essentials) ess, this);
|
||||
paperHandler.registerListeners();
|
||||
} else {
|
||||
final ChatHandler legacyHandler = new ChatHandler((Essentials) ess, this);
|
||||
legacyHandler.registerListeners();
|
||||
}
|
||||
|
||||
if (metrics == null) {
|
||||
metrics = new MetricsWrapper(this, 3814, false);
|
||||
|
@ -8,6 +8,7 @@ import com.earth2me.essentials.chat.EssentialsChat;
|
||||
import com.earth2me.essentials.utils.AdventureUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import net.ess3.api.events.LocalChatSpyEvent;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import net.essentialsx.api.v2.ChatType;
|
||||
import net.essentialsx.api.v2.events.chat.ChatEvent;
|
||||
import net.essentialsx.api.v2.events.chat.GlobalChatEvent;
|
||||
@ -22,10 +23,8 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tlLiteral;
|
||||
|
||||
@ -48,7 +47,7 @@ public abstract class AbstractChatHandler {
|
||||
* <p>
|
||||
* Handled at {@link org.bukkit.event.EventPriority#LOWEST} on both preview and chat events.
|
||||
*/
|
||||
protected void handleChatFormat(AsyncPlayerChatEvent event) {
|
||||
protected void handleChatFormat(AbstractChatEvent event) {
|
||||
if (isAborted(event)) {
|
||||
return;
|
||||
}
|
||||
@ -73,8 +72,9 @@ public abstract class AbstractChatHandler {
|
||||
final long configRadius = ess.getSettings().getChatRadius();
|
||||
chat.setRadius(Math.max(configRadius, 0));
|
||||
|
||||
final String formatted = FormatUtil.formatMessage(user, "essentials.chat", event.getMessage());
|
||||
// This listener should apply the general chat formatting only...then return control back the event handler
|
||||
event.setMessage(FormatUtil.formatMessage(user, "essentials.chat", event.getMessage()));
|
||||
event.setMessage(formatted);
|
||||
|
||||
if (ChatColor.stripColor(event.getMessage()).isEmpty()) {
|
||||
event.setCancelled(true);
|
||||
@ -110,6 +110,12 @@ public abstract class AbstractChatHandler {
|
||||
event.setMessage(event.getMessage().substring(1));
|
||||
}
|
||||
|
||||
// Prevent messages like "!&c" or "?&c" from being sent which would cause an empty message
|
||||
if (ChatColor.stripColor(event.getMessage()).isEmpty()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chat.getType() == ChatType.UNKNOWN) {
|
||||
format = AdventureUtil.miniToLegacy(tlLiteral("chatTypeLocal")).concat(format);
|
||||
} else {
|
||||
@ -128,7 +134,7 @@ public abstract class AbstractChatHandler {
|
||||
* <p>
|
||||
* Runs at {@link org.bukkit.event.EventPriority#NORMAL} priority on submitted chat events only.
|
||||
*/
|
||||
protected void handleChatRecipients(AsyncPlayerChatEvent event) {
|
||||
protected void handleChatRecipients(AbstractChatEvent event) {
|
||||
if (isAborted(event)) {
|
||||
return;
|
||||
}
|
||||
@ -151,12 +157,12 @@ public abstract class AbstractChatHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
event.getRecipients().removeIf(player -> !ess.getUser(player).isAuthorized("essentials.chat.receive.local"));
|
||||
event.removeRecipients(player -> !ess.getUser(player).isAuthorized("essentials.chat.receive.local"));
|
||||
} else {
|
||||
final String permission = "essentials.chat." + chat.getType().key();
|
||||
|
||||
if (user.isAuthorized(permission)) {
|
||||
event.getRecipients().removeIf(player -> !ess.getUser(player).isAuthorized("essentials.chat.receive." + chat.getType().key()));
|
||||
event.removeRecipients(player -> !ess.getUser(player).isAuthorized("essentials.chat.receive." + chat.getType().key()));
|
||||
|
||||
callChatEvent(event, chat.getType(), null);
|
||||
} else {
|
||||
@ -171,22 +177,10 @@ public abstract class AbstractChatHandler {
|
||||
final Location loc = user.getLocation();
|
||||
final World world = loc.getWorld();
|
||||
|
||||
final Set<Player> outList = event.getRecipients();
|
||||
final Set<Player> spyList = new HashSet<>();
|
||||
|
||||
try {
|
||||
outList.add(event.getPlayer());
|
||||
} catch (final UnsupportedOperationException ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
essChat.getLogger().log(Level.INFO, "Plugin triggered custom chat event, local chat handling aborted.", ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final Iterator<Player> it = outList.iterator();
|
||||
while (it.hasNext()) {
|
||||
final Player onlinePlayer = it.next();
|
||||
final User onlineUser = ess.getUser(onlinePlayer);
|
||||
event.removeRecipients(player -> {
|
||||
final User onlineUser = ess.getUser(player);
|
||||
if (!onlineUser.equals(user)) {
|
||||
boolean abort = false;
|
||||
final Location playerLoc = onlineUser.getLocation();
|
||||
@ -200,12 +194,13 @@ public abstract class AbstractChatHandler {
|
||||
}
|
||||
if (abort) {
|
||||
if (onlineUser.isAuthorized("essentials.chat.spy")) {
|
||||
spyList.add(onlinePlayer);
|
||||
spyList.add(player);
|
||||
}
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
callChatEvent(event, ChatType.LOCAL, chat.getRadius());
|
||||
|
||||
@ -213,7 +208,7 @@ public abstract class AbstractChatHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (outList.size() < 2) {
|
||||
if (event.recipients().size() < 2) {
|
||||
user.sendTl("localNoOne");
|
||||
}
|
||||
|
||||
@ -242,17 +237,22 @@ public abstract class AbstractChatHandler {
|
||||
* @param chatType Chat type which determines which event will be created and called.
|
||||
* @param radius If chat is a local chat, this is a non-squared radius used to calculate recipients, otherwise {@code null}.
|
||||
*/
|
||||
protected void callChatEvent(final AsyncPlayerChatEvent event, final ChatType chatType, final Long radius) {
|
||||
protected void callChatEvent(final AbstractChatEvent event, final ChatType chatType, final Long radius) {
|
||||
final ChatEvent chatEvent;
|
||||
|
||||
if (chatType == ChatType.LOCAL) {
|
||||
chatEvent = new LocalChatEvent(event.isAsynchronous(), event.getPlayer(), event.getFormat(), event.getMessage(), event.getRecipients(), radius);
|
||||
chatEvent = new LocalChatEvent(event.isAsynchronous(), event.getPlayer(), event.getFormat(), event.getMessage(), event.recipients(), radius);
|
||||
} else {
|
||||
chatEvent = new GlobalChatEvent(event.isAsynchronous(), chatType, event.getPlayer(), event.getFormat(), event.getMessage(), event.getRecipients());
|
||||
chatEvent = new GlobalChatEvent(event.isAsynchronous(), chatType, event.getPlayer(), event.getFormat(), event.getMessage(), event.recipients());
|
||||
}
|
||||
|
||||
server.getPluginManager().callEvent(chatEvent);
|
||||
|
||||
event.removeRecipients(player -> !chatEvent.getRecipients().contains(player));
|
||||
for (final Player recipient : chatEvent.getRecipients()) {
|
||||
event.addRecipient(recipient);
|
||||
}
|
||||
|
||||
event.setFormat(chatEvent.getFormat());
|
||||
event.setMessage(chatEvent.getMessage());
|
||||
event.setCancelled(chatEvent.isCancelled());
|
||||
@ -262,9 +262,9 @@ public abstract class AbstractChatHandler {
|
||||
* Finalise the formatting stage of chat processing.
|
||||
* <p>
|
||||
* Handled at {@link org.bukkit.event.EventPriority#HIGHEST} during previews, and immediately after
|
||||
* {@link #handleChatFormat(AsyncPlayerChatEvent)} when previews are not available.
|
||||
* {@link #handleChatFormat(AbstractChatEvent)} when previews are not available.
|
||||
*/
|
||||
protected void handleChatPostFormat(AsyncPlayerChatEvent event) {
|
||||
protected void handleChatPostFormat(AbstractChatEvent event) {
|
||||
if (isAborted(event)) {
|
||||
cache.clearProcessedChat(event.getPlayer());
|
||||
}
|
||||
@ -273,7 +273,7 @@ public abstract class AbstractChatHandler {
|
||||
/**
|
||||
* Run costs for chat and clean up the cached {@link com.earth2me.essentials.chat.processing.ChatProcessingCache.ProcessedChat}
|
||||
*/
|
||||
protected void handleChatSubmit(AsyncPlayerChatEvent event) {
|
||||
protected void handleChatSubmit(AbstractChatEvent event) {
|
||||
if (isAborted(event)) {
|
||||
return;
|
||||
}
|
||||
@ -284,7 +284,7 @@ public abstract class AbstractChatHandler {
|
||||
cache.clearProcessedChat(event.getPlayer());
|
||||
}
|
||||
|
||||
boolean isAborted(final AsyncPlayerChatEvent event) {
|
||||
boolean isAborted(final AbstractChatEvent event) {
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
@ -320,7 +320,7 @@ public abstract class AbstractChatHandler {
|
||||
charge.charge(user);
|
||||
}
|
||||
|
||||
boolean charge(final AsyncPlayerChatEvent event, final ChatProcessingCache.ProcessedChat chat) {
|
||||
boolean charge(final AbstractChatEvent event, final ChatProcessingCache.ProcessedChat chat) {
|
||||
try {
|
||||
charge(chat.getUser(), chat.getCharge());
|
||||
} catch (final ChargeException e) {
|
||||
|
@ -2,6 +2,7 @@ package com.earth2me.essentials.chat.processing;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.chat.EssentialsChat;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
@ -19,28 +20,33 @@ public class ChatHandler extends AbstractChatHandler {
|
||||
pm.registerEvents(new ChatHighest(), essChat);
|
||||
}
|
||||
|
||||
private class ChatLowest implements ChatListener {
|
||||
private AbstractChatEvent wrap(final AsyncPlayerChatEvent event) {
|
||||
return new SpigotChatEvent(event);
|
||||
}
|
||||
|
||||
private final class ChatLowest implements ChatListener {
|
||||
@Override
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
handleChatFormat(event);
|
||||
handleChatFormat(wrap(event));
|
||||
}
|
||||
}
|
||||
|
||||
private class ChatNormal implements ChatListener {
|
||||
private final class ChatNormal implements ChatListener {
|
||||
@Override
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
handleChatRecipients(event);
|
||||
handleChatRecipients(wrap(event));
|
||||
}
|
||||
}
|
||||
|
||||
private class ChatHighest implements ChatListener {
|
||||
private final class ChatHighest implements ChatListener {
|
||||
@Override
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
handleChatPostFormat(event);
|
||||
handleChatSubmit(event);
|
||||
final AbstractChatEvent absEvent = wrap(event);
|
||||
handleChatPostFormat(absEvent);
|
||||
handleChatSubmit(absEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.earth2me.essentials.chat.processing;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.chat.EssentialsChat;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import net.ess3.provider.providers.PaperChatListenerProvider;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
public class PaperChatHandler extends AbstractChatHandler {
|
||||
public PaperChatHandler(Essentials ess, EssentialsChat essChat) {
|
||||
super(ess, essChat);
|
||||
}
|
||||
|
||||
public void registerListeners() {
|
||||
final PluginManager pm = essChat.getServer().getPluginManager();
|
||||
pm.registerEvents(new ChatListener(), essChat);
|
||||
}
|
||||
|
||||
public final class ChatListener extends PaperChatListenerProvider {
|
||||
@Override
|
||||
public void onChatLowest(AbstractChatEvent event) {
|
||||
handleChatFormat(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChatNormal(AbstractChatEvent event) {
|
||||
handleChatRecipients(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChatHighest(AbstractChatEvent event) {
|
||||
handleChatPostFormat(event);
|
||||
handleChatSubmit(event);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.earth2me.essentials.chat.processing;
|
||||
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class SpigotChatEvent implements AbstractChatEvent {
|
||||
private final AsyncPlayerChatEvent event;
|
||||
|
||||
public SpigotChatEvent(AsyncPlayerChatEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsynchronous() {
|
||||
return event.isAsynchronous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean toCancel) {
|
||||
event.setCancelled(toCancel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return event.getFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFormat(String format) {
|
||||
event.setFormat(format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return event.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessage(String message) {
|
||||
event.setMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return event.getPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Player> recipients() {
|
||||
return Collections.unmodifiableSet(event.getRecipients());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRecipients(Predicate<Player> predicate) {
|
||||
event.getRecipients().removeIf(predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRecipient(Player player) {
|
||||
event.getRecipients().add(player);
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
const val RUN_PAPER_MINECRAFT_VERSION = "1.21.1"
|
||||
const val RUN_PAPER_MINECRAFT_VERSION = "1.21.4"
|
||||
|
@ -0,0 +1,33 @@
|
||||
package net.ess3.provider;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public interface AbstractChatEvent {
|
||||
Pattern URL_PATTERN = Pattern.compile("((?:(?:https?)://)?[\\w-_\\.]{2,})\\.([a-zA-Z]{2,3}(?:/\\S+)?)");
|
||||
|
||||
boolean isAsynchronous();
|
||||
|
||||
boolean isCancelled();
|
||||
|
||||
void setCancelled(boolean toCancel);
|
||||
|
||||
String getFormat();
|
||||
|
||||
void setFormat(String format);
|
||||
|
||||
String getMessage();
|
||||
|
||||
void setMessage(String message);
|
||||
|
||||
Player getPlayer();
|
||||
|
||||
Set<Player> recipients();
|
||||
|
||||
void removeRecipients(Predicate<Player> predicate);
|
||||
|
||||
void addRecipient(Player player);
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package net.ess3.provider.providers;
|
||||
|
||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class PaperChatEvent implements AbstractChatEvent {
|
||||
private final AsyncChatEvent event;
|
||||
private String fakeFormat;
|
||||
private String fakeMessage;
|
||||
|
||||
public PaperChatEvent(final AsyncChatEvent event) {
|
||||
this.event = event;
|
||||
this.fakeMessage = event.signedMessage().message();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsynchronous() {
|
||||
return event.isAsynchronous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean toCancel) {
|
||||
event.setCancelled(toCancel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return fakeFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFormat(String format) {
|
||||
this.fakeFormat = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return fakeMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessage(String message) {
|
||||
this.fakeMessage = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return event.getPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Player> recipients() {
|
||||
final Set<Player> recipients = new HashSet<>();
|
||||
for (final Audience recipient : event.viewers()) {
|
||||
if (recipient instanceof Player) {
|
||||
recipients.add((Player) recipient);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(recipients);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRecipients(Predicate<Player> predicate) {
|
||||
event.viewers().removeIf(recipient -> recipient instanceof Player && predicate.test((Player) recipient));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRecipient(Player player) {
|
||||
event.viewers().add(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package net.ess3.provider.providers;
|
||||
|
||||
import io.papermc.paper.chat.ChatRenderer;
|
||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||
import net.ess3.provider.AbstractChatEvent;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.flattener.ComponentFlattener;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class PaperChatListenerProvider implements Listener {
|
||||
private final LegacyComponentSerializer serializer;
|
||||
private final HashMap<AsyncChatEvent, PaperChatEvent> eventMap = new HashMap<>();
|
||||
|
||||
public PaperChatListenerProvider() {
|
||||
this.serializer = LegacyComponentSerializer.builder()
|
||||
.flattener(ComponentFlattener.basic())
|
||||
.extractUrls(AbstractChatEvent.URL_PATTERN)
|
||||
.useUnusualXRepeatedCharacterHexFormat().build();
|
||||
}
|
||||
|
||||
public abstract void onChatLowest(final AbstractChatEvent event);
|
||||
|
||||
public abstract void onChatNormal(final AbstractChatEvent event);
|
||||
|
||||
public abstract void onChatHighest(final AbstractChatEvent event);
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onLowest(final AsyncChatEvent event) {
|
||||
onChatLowest(wrap(event));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onNormal(final AsyncChatEvent event) {
|
||||
onChatNormal(wrap(event));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onHighest(final AsyncChatEvent event) {
|
||||
final PaperChatEvent paperChatEvent = wrap(event);
|
||||
onChatHighest(paperChatEvent);
|
||||
|
||||
final TextComponent format = serializer.deserialize(paperChatEvent.getFormat());
|
||||
final TextComponent eventMessage = serializer.deserialize(paperChatEvent.getMessage());
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
event.renderer(ChatRenderer.viewerUnaware((player, displayName, message) ->
|
||||
format.replaceText(builder -> builder
|
||||
.match("%(\\d)\\$s").replacement((index, match) -> {
|
||||
if (index.group(1).equals("1")) {
|
||||
return displayName;
|
||||
}
|
||||
return eventMessage;
|
||||
})
|
||||
)));
|
||||
}
|
||||
|
||||
eventMap.remove(event);
|
||||
}
|
||||
|
||||
private PaperChatEvent wrap(final AsyncChatEvent event) {
|
||||
PaperChatEvent paperChatEvent = eventMap.get(event);
|
||||
if (paperChatEvent != null) {
|
||||
return paperChatEvent;
|
||||
}
|
||||
|
||||
paperChatEvent = new PaperChatEvent(event);
|
||||
eventMap.put(event, paperChatEvent);
|
||||
|
||||
return paperChatEvent;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user