Compare commits

..

13 Commits

Author SHA1 Message Date
Aust1n46
d964918a7b
Cancel/handle plugin message events to/from client (#133)
* Cancel/handle plugin message events to/from client

* spacing
2025-02-20 00:37:16 -06:00
Aust1n46
05762e0bc7 Bugfix use 1.20.4 json boolean type for urls 2024-01-06 19:56:34 -06:00
Aust1n46
d87c255059 Support 1.20.4 2024-01-05 17:34:16 -06:00
Aust1n46
0dfd13f2de
ISSUE-80 Update server dependencies to 1.20 vers (#81) 2023-06-08 00:36:38 -05:00
Aust1n46
47fbbe23bc
Allow ignore bypass for bungeecord messaging (#66) 2023-02-09 19:09:05 -06:00
Aust1n46
314fe96e1d
Update detection of velocity enabled on paper (#64) 2023-02-09 18:39:07 -06:00
Aust1n46
d7d66e1786 Merge branch 'master' of https://github.com/Aust1n46/VentureChat 2023-02-09 18:33:15 -06:00
Aust1n46
915639d3d9 Release 3.4.5 2023-02-09 18:32:59 -06:00
LOOHP
46b0a3c36f
Escape JSON chars after parsing placeholders (#60) 2023-01-24 19:10:10 -06:00
Aust1n46
b950d21580
Merge pull request #19 from Aust1n46/issues/18
ISSUE #18 Add input validation for click_actions
2022-09-18 01:32:18 -05:00
Aust1n46
8b4666ceaf Merge branch 'master' into issues/18 2022-09-17 16:47:55 -05:00
Aust1n46
0f3b3065bd ISSUE #18 Only show hover when it is configured 2022-07-02 20:24:49 -05:00
Aust1n46
8527cb5188 ISSUE #18 Add input validation for click_actions
Refactor placeholder formatting to only apply json formatting if
configured.
2022-06-26 18:34:21 -05:00
12 changed files with 232 additions and 107 deletions

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>mineverse.Aust1n46.chat</groupId>
<artifactId>VentureChat</artifactId>
<version>3.4.3</version>
<version>3.7.2</version>
<url>https://bitbucket.org/Aust1n46/venturechat/src/master</url>
<scm>
<url>https://bitbucket.org/Aust1n46/venturechat/src/master</url>
@ -204,21 +204,21 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.13-SNAPSHOT</version>
<version>1.20-R0.1-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.13-SNAPSHOT</version>
<version>1.20-R0.1-SNAPSHOT</version>
<type>javadoc</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -0,0 +1,16 @@
package mineverse.Aust1n46.chat;
public enum ClickAction {
SUGGEST_COMMAND, RUN_COMMAND, OPEN_URL, NONE;
private final String jsonValue;
ClickAction() {
jsonValue = name().toLowerCase();
}
@Override
public String toString() {
return jsonValue;
}
}

View File

@ -79,6 +79,17 @@ public class MineverseChat extends JavaPlugin implements PluginMessageListener {
private static Permission permission = null;
private static Chat chat = null;
// TODO: This won't be so poorly done in the 4.0.0 branch I promise...
public static boolean isConnectedToProxy() {
try {
final MineverseChat plugin = MineverseChat.getInstance();
return (plugin.getServer().spigot().getConfig().getBoolean("settings.bungeecord")
|| plugin.getServer().spigot().getPaperConfig().getBoolean("settings.velocity-support.enabled")
|| plugin.getServer().spigot().getPaperConfig().getBoolean("proxies.velocity.enabled"));
} catch (final NoSuchMethodError ignored) {} // Thrown if server isn't Paper.
return false;
}
@Override
public void onEnable() {
ccInfo = new ChatChannelInfo();
@ -126,9 +137,11 @@ public class MineverseChat extends JavaPlugin implements PluginMessageListener {
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&e - Registering Listeners"));
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&e - Attaching to Executors"));
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&e - Establishing BungeeCord"));
Bukkit.getMessenger().registerOutgoingPluginChannel(this, PLUGIN_MESSAGING_CHANNEL);
Bukkit.getMessenger().registerIncomingPluginChannel(this, PLUGIN_MESSAGING_CHANNEL, this);
if (MineverseChat.isConnectedToProxy()) {
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&e - Establishing BungeeCord"));
Bukkit.getMessenger().registerOutgoingPluginChannel(this, PLUGIN_MESSAGING_CHANNEL);
Bukkit.getMessenger().registerIncomingPluginChannel(this, PLUGIN_MESSAGING_CHANNEL, this);
}
PluginManager pluginManager = getServer().getPluginManager();
if(pluginManager.isPluginEnabled("Towny")) {
@ -203,7 +216,7 @@ public class MineverseChat extends JavaPlugin implements PluginMessageListener {
}
}
}
if (getConfig().getString("loglevel", "info").equals("debug")) {
if (getConfig().getString("loglevel", "info").equals("trace")) {
Bukkit.getConsoleSender()
.sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&e - Updating Player Mutes"));
}
@ -363,6 +376,9 @@ public class MineverseChat extends JavaPlugin implements PluginMessageListener {
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] inputStream) {
if (!MineverseChat.isConnectedToProxy()) {
return;
}
if(!channel.equals(PLUGIN_MESSAGING_CHANNEL)) {
return;
}
@ -605,6 +621,15 @@ public class MineverseChat extends JavaPlugin implements PluginMessageListener {
sendPluginMessage(stream);
return;
}
if (p.getPlayer().hasPermission("venturechat.ignore.bypass")) {
out.writeUTF("Ignore");
out.writeUTF("Bypass");
out.writeUTF(server);
out.writeUTF(receiver);
out.writeUTF(sender.toString());
sendPluginMessage(stream);
return;
}
out.writeUTF("Ignore");
out.writeUTF("Echo");
out.writeUTF(server);
@ -640,6 +665,12 @@ public class MineverseChat extends JavaPlugin implements PluginMessageListener {
.replace("{player}", receiverName));
synchronize(p, true);
}
if(identifier.equals("Bypass")) {
String receiver = msgin.readUTF();
UUID sender = UUID.fromString(msgin.readUTF());
MineverseChatPlayer p = MineverseChatAPI.getOnlineMineverseChatPlayer(sender);
p.getPlayer().sendMessage(LocalizedMessage.IGNORE_PLAYER_CANT.toString().replace("{player}", receiver));
}
}
if(subchannel.equals("Mute")) {
String identifier = msgin.readUTF();

View File

@ -2,13 +2,15 @@ package mineverse.Aust1n46.chat.json;
import java.util.List;
import mineverse.Aust1n46.chat.ClickAction;
public class JsonAttribute {
private String name;
private List<String> hoverText;
private String clickAction;
private ClickAction clickAction;
private String clickText;
public JsonAttribute(String name, List<String> hoverText, String clickAction, String clickText) {
public JsonAttribute(String name, List<String> hoverText, ClickAction clickAction, String clickText) {
this.name = name;
this.hoverText = hoverText;
this.clickAction = clickAction;
@ -23,7 +25,7 @@ public class JsonAttribute {
return hoverText;
}
public String getClickAction() {
public ClickAction getClickAction() {
return clickAction;
}

View File

@ -7,58 +7,66 @@ import java.util.List;
import org.bukkit.configuration.ConfigurationSection;
import mineverse.Aust1n46.chat.ClickAction;
import mineverse.Aust1n46.chat.MineverseChat;
import mineverse.Aust1n46.chat.utilities.Format;
public class JsonFormat {
private static MineverseChat plugin = MineverseChat.getInstance();
private static HashMap<String, JsonFormat> jsonFormats;
private static MineverseChat plugin = MineverseChat.getInstance();
private static HashMap<String, JsonFormat> jsonFormats;
private List<JsonAttribute> jsonAttributes;
private int priority;
private String name;
private List<JsonAttribute> jsonAttributes;
private int priority;
private String name;
public JsonFormat(String name, int priority, List<JsonAttribute> jsonAttributes) {
this.name = name;
this.priority = priority;
this.jsonAttributes = jsonAttributes;
}
public JsonFormat(String name, int priority, List<JsonAttribute> jsonAttributes) {
this.name = name;
this.priority = priority;
this.jsonAttributes = jsonAttributes;
}
public static void initialize() {
jsonFormats = new HashMap<String, JsonFormat>();
ConfigurationSection jsonFormatSection = plugin.getConfig().getConfigurationSection("jsonformatting");
for (String jsonFormat : jsonFormatSection.getKeys(false)) {
int priority = jsonFormatSection.getInt(jsonFormat + ".priority", 0);
List<JsonAttribute> jsonAttributes = new ArrayList<>();
ConfigurationSection jsonAttributeSection = jsonFormatSection.getConfigurationSection(jsonFormat + ".json_attributes");
if (jsonAttributeSection != null) {
for (String attribute : jsonAttributeSection.getKeys(false)) {
List<String> hoverText = jsonAttributeSection.getStringList(attribute + ".hover_text");
String clickAction = jsonAttributeSection.getString(attribute + ".click_action", "");
String clickText = jsonAttributeSection.getString(attribute + ".click_text", "");
jsonAttributes.add(new JsonAttribute(attribute, hoverText, clickAction, clickText));
}
}
jsonFormats.put(jsonFormat.toLowerCase(), new JsonFormat(jsonFormat, priority, jsonAttributes));
}
}
public static void initialize() {
jsonFormats = new HashMap<String, JsonFormat>();
ConfigurationSection jsonFormatSection = plugin.getConfig().getConfigurationSection("jsonformatting");
for (String jsonFormat : jsonFormatSection.getKeys(false)) {
int priority = jsonFormatSection.getInt(jsonFormat + ".priority", 0);
List<JsonAttribute> jsonAttributes = new ArrayList<>();
ConfigurationSection jsonAttributeSection = jsonFormatSection.getConfigurationSection(jsonFormat + ".json_attributes");
if (jsonAttributeSection != null) {
for (String attribute : jsonAttributeSection.getKeys(false)) {
List<String> hoverText = jsonAttributeSection.getStringList(attribute + ".hover_text");
String clickActionText = jsonAttributeSection.getString(attribute + ".click_action", "none");
try {
ClickAction clickAction = ClickAction.valueOf(clickActionText.toUpperCase());
String clickText = jsonAttributeSection.getString(attribute + ".click_text", "");
jsonAttributes.add(new JsonAttribute(attribute, hoverText, clickAction, clickText));
} catch (IllegalArgumentException | NullPointerException exception) {
plugin.getServer().getConsoleSender()
.sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - Illegal click_action: " + clickActionText + " in jsonFormat: " + jsonFormat));
}
}
}
jsonFormats.put(jsonFormat.toLowerCase(), new JsonFormat(jsonFormat, priority, jsonAttributes));
}
}
public static Collection<JsonFormat> getJsonFormats() {
return jsonFormats.values();
}
public static Collection<JsonFormat> getJsonFormats() {
return jsonFormats.values();
}
public static JsonFormat getJsonFormat(String name) {
return jsonFormats.get(name.toLowerCase());
}
public static JsonFormat getJsonFormat(String name) {
return jsonFormats.get(name.toLowerCase());
}
public String getName() {
return name;
}
public String getName() {
return name;
}
public int getPriority() {
return priority;
}
public int getPriority() {
return priority;
}
public List<JsonAttribute> getJsonAttributes() {
return jsonAttributes;
}
public List<JsonAttribute> getJsonAttributes() {
return jsonAttributes;
}
}

View File

@ -73,19 +73,14 @@ public class LoginListener implements Listener {
}
}
try {
if(plugin.getServer().spigot().getConfig().getBoolean("settings.bungeecord") || plugin.getServer().spigot().getPaperConfig().getBoolean("settings.velocity-support.enabled")) {
long delayInTicks = 20L;
final MineverseChatPlayer sync = mcp;
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
public void run() {
MineverseChat.synchronize(sync, false);
}
}, delayInTicks);
}
}
catch(NoSuchMethodError exception) { // Thrown if server isn't Paper.
// Do nothing
if (MineverseChat.isConnectedToProxy()) {
long delayInTicks = 20L;
final MineverseChatPlayer sync = mcp;
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
public void run() {
MineverseChat.synchronize(sync, false);
}
}, delayInTicks);
}
}
}

View File

@ -105,6 +105,9 @@ public class VentureChatBungee extends Plugin implements Listener, VentureChatPr
if(!event.getTag().equals(VentureChatProxy.PLUGIN_MESSAGING_CHANNEL_STRING) && !event.getTag().contains("viaversion:")) {
return;
}
// Critical to prevent client from sending or receiving messages
event.setCancelled(true);
if(!(event.getSender() instanceof Server)) {
return;
}

View File

@ -205,6 +205,18 @@ public class VentureChatProxy {
source.sendPluginMessage(server, outstream.toByteArray());
}
}
if(identifier.equals("Bypass")) {
String server = in.readUTF();
String player = in.readUTF();
String sender = in.readUTF();
out.writeUTF("Ignore");
out.writeUTF("Bypass");
out.writeUTF(player);
out.writeUTF(sender);
if(!source.getServer(server).isEmpty()) {
source.sendPluginMessage(server, outstream.toByteArray());
}
}
}
if(subchannel.equals("Mute")) {
String identifier = in.readUTF();

View File

@ -134,12 +134,14 @@ public class VentureChatVelocity implements VentureChatProxySource {
if(!channelIdentifierId.equals(VentureChatProxy.PLUGIN_MESSAGING_CHANNEL_STRING) && !channelIdentifierId.contains("viaversion:")) {
return;
}
// Critical to prevent client from sending or receiving messages
event.setResult(ForwardResult.handled());
if(!(event.getSource() instanceof ServerConnection)) {
return;
}
String serverName = ((ServerConnection) event.getSource()).getServerInfo().getName();
VentureChatProxy.onPluginMessage(event.getData(), serverName, this);
event.setResult(ForwardResult.handled());
}
@Override

View File

@ -10,6 +10,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
@ -22,6 +23,7 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import me.clip.placeholderapi.PlaceholderAPI;
import mineverse.Aust1n46.chat.ClickAction;
import mineverse.Aust1n46.chat.api.MineverseChatAPI;
import mineverse.Aust1n46.chat.api.MineverseChatPlayer;
import mineverse.Aust1n46.chat.json.JsonAttribute;
@ -66,10 +68,9 @@ public class Format {
*/
public static String convertToJson(MineverseChatPlayer sender, String format, String chat) {
JsonFormat JSONformat = JsonFormat.getJsonFormat(sender.getJsonFormat());
String f = escapeJsonChars(format);
String c = escapeJsonChars(chat);
String json = "[\"\",{\"text\":\"\",\"extra\":[";
json += convertPlaceholders(f, JSONformat, sender);
json += convertPlaceholders(format, JSONformat, sender);
json += "]}";
json += "," + convertLinks(c);
json += "]";
@ -109,31 +110,48 @@ public class Format {
indexStart = matcher.start();
indexEnd = matcher.end();
placeholder = remaining.substring(indexStart, indexEnd);
formattedPlaceholder = Format.FormatStringAll(PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), placeholder));
temp += convertToJsonColors(lastCode + remaining.substring(0, indexStart)) + ",";
formattedPlaceholder = escapeJsonChars(Format.FormatStringAll(PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), placeholder)));
temp += convertToJsonColors(escapeJsonChars(lastCode + remaining.substring(0, indexStart))) + ",";
lastCode = getLastCode(lastCode + remaining.substring(0, indexStart));
String action = "";
String text = "";
String hover = "";
boolean placeholderHasJsonAttribute = false;
for (JsonAttribute jsonAttribute : format.getJsonAttributes()) {
if (placeholder.contains(jsonAttribute.getName().replace("{", "").replace("}", ""))) {
action = jsonAttribute.getClickAction();
text = Format.FormatStringAll(
PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), jsonAttribute.getClickText()));
final StringBuilder hover = new StringBuilder();
for (String st : jsonAttribute.getHoverText()) {
hover += Format.FormatStringAll(st) + "\n";
hover.append(Format.FormatStringAll(st) + "\n");
}
final String hoverText;
if(!hover.isEmpty()) {
hoverText = escapeJsonChars(Format.FormatStringAll(
PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), hover.substring(0, hover.length() - 1))));
} else {
hoverText = StringUtils.EMPTY;
}
final ClickAction clickAction = jsonAttribute.getClickAction();
final String actionJson;
if (clickAction == ClickAction.NONE) {
actionJson = StringUtils.EMPTY;
} else {
final String clickText = escapeJsonChars(Format.FormatStringAll(
PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), jsonAttribute.getClickText())));
actionJson = ",\"clickEvent\":{\"action\":\"" + jsonAttribute.getClickAction().toString() + "\",\"value\":\"" + clickText
+ "\"}";
}
final String hoverJson;
if (hoverText.isEmpty()) {
hoverJson = StringUtils.EMPTY;
} else {
hoverJson = ",\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":["
+ convertToJsonColors(hoverText) + "]}}";
}
temp += convertToJsonColors(lastCode + formattedPlaceholder, actionJson + hoverJson) + ",";
placeholderHasJsonAttribute = true;
break;
}
}
if(!hover.isEmpty()) {
hover = Format.FormatStringAll(
PlaceholderAPI.setBracketPlaceholders(icp.getPlayer(), hover.substring(0, hover.length() - 1)));
if (!placeholderHasJsonAttribute) {
temp += convertToJsonColors(lastCode + formattedPlaceholder) + ",";
}
temp += convertToJsonColors(lastCode + formattedPlaceholder,
",\"clickEvent\":{\"action\":\"" + action + "\",\"value\":\"" + text
+ "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":["
+ convertToJsonColors(hover) + "]}}")
+ ",";
lastCode = getLastCode(lastCode + formattedPlaceholder);
remaining = remaining.substring(indexEnd);
} else {
@ -172,8 +190,8 @@ public class Format {
if (ChatColor.stripColor(link).contains("https://"))
https = "s";
temp += convertToJsonColors(lastCode + link,
",\"underlined\":\"" + underlineURLs()
+ "\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http" + https + "://"
",\"underlined\":" + underlineURLs()
+ ",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"http" + https + "://"
+ ChatColor.stripColor(link.replace("http://", "").replace("https://", ""))
+ "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":["
+ convertToJsonColors(lastCode + link) + "]}}")
@ -325,15 +343,35 @@ public class Format {
underlined = false;
}
if (bold)
modifier += ",\"bold\":\"true\"";
if (VersionHandler.isAtLeast_1_20_4()) {
modifier += ",\"bold\":true";
} else {
modifier += ",\"bold\":\"true\"";
}
if (obfuscated)
modifier += ",\"obfuscated\":\"true\"";
if (VersionHandler.isAtLeast_1_20_4()) {
modifier += ",\"obfuscated\":true";
} else {
modifier += ",\"obfuscated\":\"true\"";
}
if (italic)
modifier += ",\"italic\":\"true\"";
if (VersionHandler.isAtLeast_1_20_4()) {
modifier += ",\"italic\":true";
} else {
modifier += ",\"italic\":\"true\"";
}
if (underlined)
modifier += ",\"underlined\":\"true\"";
if (VersionHandler.isAtLeast_1_20_4()) {
modifier += ",\"underlined\":true";
} else {
modifier += ",\"underlined\":\"true\"";
}
if (strikethrough)
modifier += ",\"strikethrough\":\"true\"";
if (VersionHandler.isAtLeast_1_20_4()) {
modifier += ",\"strikethrough\":true";
} else {
modifier += ",\"strikethrough\":\"true\"";
}
remaining = remaining.substring(colorLength);
colorLength = LEGACY_COLOR_CODE_LENGTH;
indexNextColor = remaining.indexOf(BUKKIT_COLOR_CODE_PREFIX);
@ -430,16 +468,20 @@ public class Format {
public static PacketContainer createPacketPlayOutChat(String json) {
final PacketContainer container;
if (VersionHandler.isAbove_1_19()) {
if (VersionHandler.isAtLeast_1_20_4()) { // 1.20.4+
container = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
container.getChatComponents().write(0, WrappedChatComponent.fromJson(json));
container.getBooleans().write(0, false);
} else if (VersionHandler.isAbove_1_19()) { // 1.19.1 -> 1.20.3
container = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
container.getStrings().write(0, json);
container.getBooleans().write(0, false);
} else if (VersionHandler.isUnder_1_19()) {
} else if (VersionHandler.isUnder_1_19()) { // 1.7 -> 1.19
WrappedChatComponent component = WrappedChatComponent.fromJson(json);
container = new PacketContainer(PacketType.Play.Server.CHAT);
container.getModifier().writeDefaults();
container.getChatComponents().write(0, component);
} else {
} else { // 1.19
container = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
container.getStrings().write(0, json);
container.getIntegers().write(0, 1);
@ -449,15 +491,19 @@ public class Format {
public static PacketContainer createPacketPlayOutChat(WrappedChatComponent component) {
final PacketContainer container;
if (VersionHandler.isAbove_1_19()) {
if (VersionHandler.isAtLeast_1_20_4()) { // 1.20.4+
container = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
container.getChatComponents().write(0, component);
container.getBooleans().write(0, false);
} else if (VersionHandler.isAbove_1_19()) { // 1.19.1 -> 1.20.3
container = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
container.getStrings().write(0, component.getJson());
container.getBooleans().write(0, false);
} else if (VersionHandler.isUnder_1_19()) {
} else if (VersionHandler.isUnder_1_19()) { // 1.7 -> 1.19
container = new PacketContainer(PacketType.Play.Server.CHAT);
container.getModifier().writeDefaults();
container.getChatComponents().write(0, component);
} else {
} else { // 1.19
container = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
container.getStrings().write(0, component.getJson());
container.getIntegers().write(0, 1);
@ -765,8 +811,13 @@ public class Format {
.replace(")", "\\)").replace("|", "\\|").replace("+", "\\+").replace("*", "\\*");
}
public static boolean underlineURLs() {
return getInstance().getConfig().getBoolean("underlineurls", true);
public static String underlineURLs() {
final boolean configValue = getInstance().getConfig().getBoolean("underlineurls", true);
if (VersionHandler.isAtLeast_1_20_4()) {
return String.valueOf(configValue);
} else {
return "\"" + configValue + "\"";
}
}
public static String parseTimeStringFromMillis(long millis) {

View File

@ -7,6 +7,7 @@ public final class VersionHandler {
public static final MinecraftVersion SERVER_VERSION = MinecraftVersion.getCurrentVersion();
private static final MinecraftVersion MC1_19 = new MinecraftVersion(1, 19, 0);
private static final MinecraftVersion MC1_19_1 = new MinecraftVersion(1, 19, 1);
private static final MinecraftVersion MC1_20_4 = new MinecraftVersion(1, 20, 4);
private VersionHandler() {
}
@ -74,4 +75,8 @@ public final class VersionHandler {
public static boolean isAbove_1_19() {
return SERVER_VERSION.isAtLeast(MC1_19_1);
}
public static boolean isAtLeast_1_20_4() {
return SERVER_VERSION.isAtLeast(MC1_20_4);
}
}

View File

@ -136,7 +136,7 @@ messageremovertext: '&c&o<message removed>'
# The name of the group is the permissions node for the format
# Example: venturechat.json.Owner is the node for the group Owner
# A lower priority overrides a higher priority if a player has more than 1 group
# Possible options for click_name and click_prefix are suggest_command, run_command, and open_url
# Possible options for click_action are suggest_command, run_command, open_url, and none
jsonformatting:
Default: # This default format is required! Do not delete or rename it!
priority: 2147483647 # Integer.MAX_VALUE