Skip to content

Commit

Permalink
Merge pull request #170 from Brikster/dev
Browse files Browse the repository at this point in the history
Release 2.19.9
  • Loading branch information
Brikster authored Jun 16, 2022
2 parents 7f42a66 + 2426e2c commit f51bc50
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 72 deletions.
5 changes: 2 additions & 3 deletions api/src/main/java/net/amoebaman/util/ArrayWrapper.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package net.amoebaman.util;

import org.apache.commons.lang.Validate;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;

/**
* Represents a wrapper around an array class of an arbitrary reference type,
Expand Down Expand Up @@ -46,7 +45,7 @@ public E[] getArray() {
* @param array The new wrapped array.
*/
public void setArray(E[] array) {
Validate.notNull(array, "The array must not be null.");
Objects.requireNonNull(array, "The array must not be null.");
_array = array;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.bukkit.entity.Player;
import ru.mrbrikster.chatty.json.fanciful.FancyMessage;

import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -23,7 +26,7 @@ public FormattedMessage(String text, boolean colorize) {
this.messageParts.add(new LegacyMessagePart(text, colorize));
}

public FormattedMessage send(Collection<? extends Player> players, UUID sender) {
public FormattedMessage send(Collection<? extends Player> players, Player sender) {
toFancyMessage().send(players, sender);

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,11 +569,11 @@ public String toJSONString() {
*
* @param player The player who will receive the message.
*/
public void send(Player player, UUID sender) {
public void send(Player player, Player sender) {
send(player, toJSONString(), sender);
}

private void send(CommandSender sender, String jsonString, UUID from) {
private void send(CommandSender sender, String jsonString, Player from) {
if (!(sender instanceof Player)) {
sender.sendMessage(toOldMessageFormat());
return;
Expand All @@ -590,7 +590,7 @@ private void send(CommandSender sender, String jsonString, UUID from) {
* @param sender The command sender who will receive the message.
* @see #toOldMessageFormat()
*/
public void send(CommandSender sender, UUID from) {
public void send(CommandSender sender, Player from) {
send(sender, toJSONString(), from);
}

Expand All @@ -600,7 +600,7 @@ public void send(CommandSender sender, UUID from) {
* @param senders The command senders who will receive the message.
* @see #send(CommandSender)
*/
public void send(final Iterable<? extends CommandSender> senders, UUID from) {
public void send(final Iterable<? extends CommandSender> senders, Player from) {
String string = toJSONString();

for (final CommandSender sender : senders) {
Expand Down
133 changes: 88 additions & 45 deletions api/src/main/java/ru/mrbrikster/chatty/util/textapi/NMSUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,41 @@
import java.util.HashMap;
import java.util.UUID;

import static ru.mrbrikster.chatty.util.textapi.NMSUtil.ServerPackage.*;

@UtilityClass
public class NMSUtil {

private static final HashMap<String, Class<?>> NMS_CLASSES = new HashMap<>();

static {
NMS_CLASSES.put("IChatBaseComponent", resolveSuitableClass(ServerPackage.MINECRAFT + ".IChatBaseComponent",
ServerPackage.NETWORK + ".chat.IChatBaseComponent"));
NMS_CLASSES.put("ChatMessageType", resolveSuitableClass(ServerPackage.MINECRAFT + ".ChatMessageType",
ServerPackage.NETWORK + ".chat.ChatMessageType"));
NMS_CLASSES.put("IChatBaseComponent$ChatSerializer", resolveSuitableClass(ServerPackage.MINECRAFT + ".IChatBaseComponent$ChatSerializer",
ServerPackage.NETWORK + ".chat.IChatBaseComponent$ChatSerializer"));

NMS_CLASSES.put("PacketPlayOutChat", resolveSuitableClass(ServerPackage.MINECRAFT + ".PacketPlayOutChat",
ServerPackage.NETWORK + ".protocol.game.PacketPlayOutChat"));
NMS_CLASSES.put("Packet", resolveSuitableClass(ServerPackage.MINECRAFT + ".Packet",
ServerPackage.NETWORK + ".protocol.Packet"));
NMS_CLASSES.put("IChatBaseComponent", resolveSuitableClass(MINECRAFT + ".IChatBaseComponent",
NETWORK + ".chat.IChatBaseComponent"));
NMS_CLASSES.put("ChatMessageType", resolveSuitableClass(MINECRAFT + ".ChatMessageType",
NETWORK + ".chat.ChatMessageType"));
NMS_CLASSES.put("IChatBaseComponent$ChatSerializer", resolveSuitableClass(MINECRAFT + ".IChatBaseComponent$ChatSerializer",
NETWORK + ".chat.IChatBaseComponent$ChatSerializer"));

NMS_CLASSES.put("PacketPlayOutChat", resolveSuitableClass(MINECRAFT + ".PacketPlayOutChat",
NETWORK + ".protocol.game.PacketPlayOutChat"));
NMS_CLASSES.put("Packet", resolveSuitableClass(MINECRAFT + ".Packet",
NETWORK + ".protocol.Packet"));

// Legacy title packets
NMS_CLASSES.put("PacketPlayOutTitle", resolveSuitableClass(ServerPackage.MINECRAFT + ".PacketPlayOutTitle"));
NMS_CLASSES.put("PacketPlayOutTitle$EnumTitleAction", resolveSuitableClass(ServerPackage.MINECRAFT + ".PacketPlayOutTitle$EnumTitleAction"));
NMS_CLASSES.put("PacketPlayOutTitle", resolveSuitableClass(MINECRAFT + ".PacketPlayOutTitle"));
NMS_CLASSES.put("PacketPlayOutTitle$EnumTitleAction", resolveSuitableClass(MINECRAFT + ".PacketPlayOutTitle$EnumTitleAction"));

// New (>= 1.17) title packets
NMS_CLASSES.put("ClientboundSetTitleTextPacket", resolveSuitableClass(ServerPackage.NETWORK + ".protocol.game.ClientboundSetTitleTextPacket"));
NMS_CLASSES.put("ClientboundSetSubtitleTextPacket", resolveSuitableClass(ServerPackage.NETWORK + ".protocol.game.ClientboundSetSubtitleTextPacket"));
NMS_CLASSES.put("ClientboundSetTitlesAnimationPacket", resolveSuitableClass(ServerPackage.NETWORK + ".protocol.game.ClientboundSetTitlesAnimationPacket"));
NMS_CLASSES.put("ClientboundSetTitleTextPacket", resolveSuitableClass(NETWORK + ".protocol.game.ClientboundSetTitleTextPacket"));
NMS_CLASSES.put("ClientboundSetSubtitleTextPacket", resolveSuitableClass(NETWORK + ".protocol.game.ClientboundSetSubtitleTextPacket"));
NMS_CLASSES.put("ClientboundSetTitlesAnimationPacket", resolveSuitableClass(NETWORK + ".protocol.game.ClientboundSetTitlesAnimationPacket"));

// 1.19 chat packet
NMS_CLASSES.put("ClientboundPlayerChatPacket", resolveSuitableClass(NETWORK + ".protocol.game.ClientboundPlayerChatPacket"));
NMS_CLASSES.put("IChatMutableComponent", resolveSuitableClass(NETWORK + ".protocol.game.IChatMutableComponent"));
NMS_CLASSES.put("PlayerChatMessage", resolveSuitableClass(NETWORK + ".chat.PlayerChatMessage"));
NMS_CLASSES.put("ServerPlayer", resolveSuitableClass("net.minecraft.server.level.ServerPlayer"));
NMS_CLASSES.put("ChatSender", resolveSuitableClass(NETWORK + ".chat.ChatSender"));
}

public Class<?> getClass(String key) {
Expand Down Expand Up @@ -64,47 +73,81 @@ public Field resolveField(Class<?> clazz, String... names) {
throw new IllegalStateException();
}

public void sendChatPacket(Player player, String type, String text, UUID sender) {
public void sendChatPacket(Player player, String type, String text, Player sender) {
try {
Class<?> clsIChatBaseComponent = NMS_CLASSES.get("IChatBaseComponent");
Class<?> clsChatMessageType = NMS_CLASSES.get("ChatMessageType");
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
Object playerConnection = resolveField(entityPlayer.getClass(), "b", "playerConnection").get(entityPlayer);
Object chatBaseComponent = NMS_CLASSES.get("IChatBaseComponent$ChatSerializer").getMethod("a", String.class).invoke(null, text);
Object chatMessageType = clsChatMessageType.getMethod("valueOf", String.class).invoke(null, type);

Object packetPlayOutChat = null;
Class<?> packetPlayOutChatClass = NMS_CLASSES.get("PacketPlayOutChat");
Class<?> clsClientboundPlayerChatPacket = NMS_CLASSES.get("ClientboundPlayerChatPacket");

// Legacy versions (< 1.16)
try {
packetPlayOutChat = packetPlayOutChatClass.getConstructor(clsIChatBaseComponent, clsChatMessageType)
.newInstance(chatBaseComponent, chatMessageType);
} catch (Throwable ignored) {}
if (clsClientboundPlayerChatPacket == null) {
// < 1.19
Class<?> clsChatMessageType = NMS_CLASSES.get("ChatMessageType");
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
Object playerConnection = resolveField(entityPlayer.getClass(), "b", "playerConnection").get(entityPlayer);
Object chatMessageType = clsChatMessageType.getMethod("valueOf", String.class).invoke(null, type);

Object packetPlayOutChat = null;
Class<?> packetPlayOutChatClass = NMS_CLASSES.get("PacketPlayOutChat");

// New versions (>= 1.16)
if (packetPlayOutChat == null) {
// Legacy versions (< 1.16)
try {
packetPlayOutChat = packetPlayOutChatClass.getConstructor(clsIChatBaseComponent, clsChatMessageType, UUID.class)
.newInstance(chatBaseComponent, chatMessageType, sender);
packetPlayOutChat = packetPlayOutChatClass.getConstructor(clsIChatBaseComponent, clsChatMessageType)
.newInstance(chatBaseComponent, chatMessageType);
} catch (Throwable ignored) {}
}

if (packetPlayOutChat == null) {
throw new IllegalStateException();
}
// New versions (>= 1.16)
if (packetPlayOutChat == null) {
try {
packetPlayOutChat = packetPlayOutChatClass.getConstructor(clsIChatBaseComponent, clsChatMessageType, UUID.class)
.newInstance(chatBaseComponent, chatMessageType, sender.getUniqueId());
} catch (Throwable ignored) {}
}

Method sendPacketMethod;
try {
sendPacketMethod = playerConnection.getClass().getMethod("sendPacket", NMS_CLASSES.get("Packet"));
} catch (Exception ignored) {
// 1.18+
sendPacketMethod = playerConnection.getClass().getMethod("a", NMS_CLASSES.get("Packet"));
}
if (packetPlayOutChat == null) {
throw new IllegalStateException();
}

sendPacketMethod.invoke(playerConnection, packetPlayOutChat);
Method sendPacketMethod;
try {
sendPacketMethod = playerConnection.getClass().getMethod("sendPacket", NMS_CLASSES.get("Packet"));
} catch (Exception ignored) {
// 1.18+
sendPacketMethod = playerConnection.getClass().getMethod("a", NMS_CLASSES.get("Packet"));
}

sendPacketMethod.invoke(playerConnection, packetPlayOutChat);
} else {
// 1.19+
Class<?> clsChatSender = NMS_CLASSES.get("ChatSender");
Class<?> clsPlayerChatMessage = NMS_CLASSES.get("PlayerChatMessage");

// ChatMessageType chatMessageType = type.equals("CHAT") ? ChatMessageType.b : ChatMessageType.d;
Object chatMessageType = NMS_CLASSES.get("ChatMessageType")
// b: 'system', d: 'game_info'
.getDeclaredField(type.equals("CHAT") ? "c" : "d")
.get(null);

Object senderName = NMS_CLASSES.get("IChatBaseComponent$ChatSerializer")
.getMethod("a", String.class)
.invoke(null, "{\"text\":\"" + player.getDisplayName() + "\"}");

// PlayerChatMessage playerChatMessage = PlayerChatMessage.a(chatBaseComponent);
Object playerChatMessage = clsPlayerChatMessage.getMethod("a", clsIChatBaseComponent)
.invoke(null, chatBaseComponent);

// ChatSender chatSender = new ChatSender(sender, senderName);
Object chatSender = clsChatSender.getConstructor(UUID.class, clsIChatBaseComponent)
.newInstance(sender.getUniqueId(), senderName);

// EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
// entityPlayer.a(playerChatMessage, chatSender, chatMessageType);
entityPlayer.getClass().getMethod("a", clsPlayerChatMessage, clsChatSender, chatMessageType.getClass())
.invoke(entityPlayer, playerChatMessage, chatSender, chatMessageType);
}
} catch (Throwable e) {
throw new RuntimeException("NMS features is not supported by Chatty on your server version (" + ServerPackage.getServerVersion() + ")", e);
throw new RuntimeException("NMS features is not supported by Chatty on your server version (" + getServerVersion() + ")", e);
}
}

Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
allprojects {
group = 'ru.mrbrikster'
version = '2.19.8'
version = '2.19.9'
}

subprojects {
Expand Down Expand Up @@ -33,6 +33,6 @@ subprojects {
compileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'

compileOnly 'org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT'
}
}
4 changes: 2 additions & 2 deletions spigot/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ tasks {
}

runServer {
minecraftVersion('1.18.2')
minecraftVersion('1.19')
}
}

Expand All @@ -33,7 +33,7 @@ processResources {
dependencies {
api project(':api')
api 'com.github.Brikster:BasePlugin:v1.8'
api 'com.google.code.gson:gson:2.8.5'
api 'com.google.code.gson:gson:2.8.9'
api 'org.bstats:bstats-bukkit:2.2.1'

compileOnly 'net.milkbowl.vault:VaultAPI:1.7'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ private void performJsonMessage(AsyncPlayerChatEvent event, Chat chat) {
if (configuration.getNode("json.swears.enable").getAsBoolean(false)) {
applyJsonSwears(event, formattedMessage);
} else {
formattedMessage.send(event.getRecipients(), event.getPlayer().getUniqueId());
formattedMessage.send(event.getRecipients(), event.getPlayer());
}

event.setFormat(formattedMessage.toReadableText().replace("%", "%%"));
Expand All @@ -393,7 +393,7 @@ private void applyJsonSwears(AsyncPlayerChatEvent event, FormattedMessage format
List<String> swears = pendingSwears.remove(event.getPlayer());

if (swears == null) {
formattedMessage.send(event.getRecipients(), event.getPlayer().getUniqueId());
formattedMessage.send(event.getRecipients(), event.getPlayer());
} else {
List<Player> canSeeSwears = new ArrayList<>();
List<Player> cannotSeeSwears = new ArrayList<>();
Expand All @@ -406,7 +406,7 @@ private void applyJsonSwears(AsyncPlayerChatEvent event, FormattedMessage format
}
});

formattedMessage.send(cannotSeeSwears, event.getPlayer().getUniqueId());
formattedMessage.send(cannotSeeSwears, event.getPlayer());

List<String> swearTooltip = configuration.getNode("json.swears.tooltip").getAsStringList()
.stream().map(TextUtil::stylish).collect(Collectors.toList());
Expand All @@ -419,7 +419,7 @@ private void applyJsonSwears(AsyncPlayerChatEvent event, FormattedMessage format
.collect(Collectors.toList()))
.suggest(suggest != null ? suggest.replace("{word}", swear) : null)));

formattedMessage.send(canSeeSwears, event.getPlayer().getUniqueId());
formattedMessage.send(canSeeSwears, event.getPlayer());
}
}

Expand Down
20 changes: 13 additions & 7 deletions spigot/src/main/java/ru/mrbrikster/chatty/chat/JsonStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,20 @@ public Optional<JsonElement> getProperty(Player player, String property) {
}

public boolean isIgnore(CommandSender recipient, CommandSender sender) {
if (recipient instanceof Player) {
JsonElement jsonElement = getProperty((Player) recipient, "ignore").orElseGet(JsonArray::new);

if (!jsonElement.isJsonArray())
jsonElement = new JsonArray();
if (sender != null) {
JsonElement jsonElement = Chatty.instance().getExact(JsonStorage.class)
.getProperty((Player)recipient, "ignore").orElseGet(JsonArray::new);

if (jsonElement.isJsonArray()) {
for (JsonElement ignoreJsonElement : jsonElement.getAsJsonArray()) {
if (sender.getName().equalsIgnoreCase(ignoreJsonElement.getAsString())) {
return true;
}
}
}

return jsonElement.getAsJsonArray().contains(new JsonPrimitive(sender.getName()));
}
return false;
}

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import ru.mrbrikster.chatty.moderation.AdvertisementModerationMethod;
import ru.mrbrikster.chatty.moderation.ModerationManager;
import ru.mrbrikster.chatty.moderation.SwearModerationMethod;
import ru.mrbrikster.chatty.util.Sound;
import ru.mrbrikster.chatty.util.TextUtil;

public abstract class PrivateMessageCommand extends BukkitCommand {
Expand Down Expand Up @@ -119,7 +120,15 @@ protected void handlePrivateMessage(@NotNull CommandSender sender, @NotNull Comm
recipient.sendMessage(recipientFormat);
} else {
new FancyMessage(recipientFormat)
.send(recipient, sender instanceof Player ? ((Player) sender).getUniqueId() : null);
.send(recipient, sender instanceof Player ? ((Player) sender) : null);

String soundName = configuration.getNode("pm.sound").getAsString(null);
if (soundName != null) {
org.bukkit.Sound sound = Sound.byName(soundName);
double soundVolume = (double) configuration.getNode("pm.sound-volume").get(1d);
double soundPitch = (double) configuration.getNode("pm.sound-pitch").get(1d);
((Player) recipient).playSound(((Player) recipient).getLocation(), sound, (float) soundVolume, (float) soundPitch);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ public void onJoin(PlayerJoinEvent event) {
soundPitch = (double) configuration.getNode("miscellaneous.vanilla.first-join.sound-pitch").get(1d);
}

System.out.println(soundVolume + " " + soundPitch);

boolean hasPermission = !configuration.getNode("miscellaneous.vanilla.join.permission").getAsBoolean(true)
|| event.getPlayer().hasPermission("chatty.misc.joinmessage");

Expand Down
8 changes: 8 additions & 0 deletions spigot/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ pm:
recipient: '&7{sender-prefix}{sender-name} &6-> &7{recipient-prefix}{recipient-name}: &f{message}'
sender: '&7{sender-prefix}{sender-name} &6-> &7{recipient-prefix}{recipient-name}: &f{message}'

# Plays sound to recipient
# Remove the line if not needed.
sound: CLICK

# Sound volume and pitch parameters
sound-volume: 1.0
sound-pitch: 1.0

commands:
msg:
# Enables "/msg" command.
Expand Down

0 comments on commit f51bc50

Please sign in to comment.