Compare commits

..

1 commit

Author SHA1 Message Date
dependabot[bot] f4a6b5d2d7
Bump log4j-core from 2.17.0 to 2.17.1
Bumps log4j-core from 2.17.0 to 2.17.1.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 16:36:18 +00:00
31 changed files with 468 additions and 426 deletions

65
pom.xml
View file

@ -66,6 +66,21 @@
</useSystemClassLoader> <!-- https://stackoverflow.com/a/53012553/2703239 -->
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-testCompile</id>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<groupId>buttondevteam</groupId>
@ -100,23 +115,18 @@
<id>Dynmap</id>
<url>https://repo.mikeprimm.com</url>
</repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency> <!-- TODO: Can't update MockBukkit because of a ByteBuddy exception and the old version relies on 1.19.1 -->
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.19.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.TBMCPlugins.ChromaCore</groupId>
<artifactId>Chroma-Core</artifactId>
<version>v2.0.0-SNAPSHOT</version>
</dependency>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.TBMCPlugins.ChromaCore</groupId>
<artifactId>Chroma-Core</artifactId>
<version>v1.0.0</version>
</dependency>
<dependency>
<groupId>net.essentialsx</groupId>
<artifactId>EssentialsX</artifactId>
@ -127,7 +137,7 @@
<groupId>com.github.TownyAdvanced</groupId>
<artifactId>Towny</artifactId>
<!-- <version>8d3b6b6</version> ButtonCore repo -->
<version>0.98.6.0</version>
<version>0.96.2.0</version>
<scope>provided</scope>
</dependency>
<!-- <dependency> <groupId>au.com.mineauz</groupId> <artifactId>Minigames</artifactId>
@ -146,6 +156,12 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
@ -172,7 +188,7 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.0</version>
<version>2.17.1</version>
<scope>provided</scope>
</dependency>
<!-- TestPrepare also needs it (ChromaCore) so the versions should match -->
@ -182,19 +198,6 @@
<version>4.2.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mojang/brigadier -->
<dependency>
<groupId>com.mojang</groupId>
<artifactId>brigadier</artifactId>
<version>1.0.500</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.19</artifactId>
<version>2.29.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<artifactId>Chroma-Chat</artifactId>
<organization>

View file

@ -1,34 +1,32 @@
package buttondevteam.chat;
import buttondevteam.chat.components.flair.FlairStates;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.config.IListConfigData;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.architecture.ListConfigData;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.player.PlayerClass;
import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Collections;
@PlayerClass(pluginname = "Chroma-Chat")
public class ChatPlayer extends TBMCPlayerBase {
public final IConfigData<String> UserName = getConfig().getData("UserName", "");
public final ConfigData<String> UserName = getConfig().getData("UserName", "");
public final IListConfigData<String> UserNames = getConfig().getListData("UserNames", Collections.emptyList());
public final ListConfigData<String> UserNames = getConfig().getListData("UserNames");
public final IConfigData<Integer> FlairTime = getConfig().getData("FlairTime", FlairTimeNone);
public final ConfigData<Integer> FlairTime = getConfig().getData("FlairTime", FlairTimeNone);
public final IConfigData<FlairStates> FlairState = getConfig().getData("FlairState", FlairStates.NoComment,
public final ConfigData<FlairStates> FlairState = getConfig().getData("FlairState", FlairStates.NoComment,
fs -> FlairStates.valueOf((String) fs), FlairStates::toString);
public final IConfigData<Integer> FCount = getConfig().getData("FCount", 0);
public final ConfigData<Integer> FCount = getConfig().getData("FCount", 0);
public final IConfigData<Integer> FDeaths = getConfig().getData("FDeaths", 0);
public final ConfigData<Integer> FDeaths = getConfig().getData("FDeaths", 0);
public final IConfigData<Boolean> FlairCheater = getConfig().getData("FlairCheater", false);
public final ConfigData<Boolean> FlairCheater = getConfig().getData("FlairCheater", false);
public final IListConfigData<Integer> NameColorLocations = getConfig().getListData("NameColorLocations", Collections.emptyList()); // No byte[], no TIntArrayList
public final ListConfigData<Integer> NameColorLocations = getConfig().getListData("NameColorLocations"); // No byte[], no TIntArrayList
public boolean Working;
// public int Tables = 10;
@ -82,7 +80,7 @@ public class ChatPlayer extends TBMCPlayerBase {
// Flairs from Command Block The Button - Teams
// PluginMain.Instance.getServer().getScoreboardManager().getMainScoreboard().getTeams().add()
Player p = Bukkit.getPlayer(getUniqueId());
Player p = Bukkit.getPlayer(uuid);
if (p != null)
p.setPlayerListName(String.format("%s%s", p.getDisplayName(), GetFormattedFlair()));
}

View file

@ -1,8 +1,8 @@
package buttondevteam.chat;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.player.ChromaGamerBase;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -48,18 +48,19 @@ public final class ChatUtils {
* @param e The chat event
*/
public static void sendChatMessage(TBMCChatEvent e) {
var str = getMessageString(e.getChannel(), e.getUser(), e.getMessage());
var str = getMessageString(e.getChannel(), e.getSender(), e.getMessage());
for (Player p : Bukkit.getOnlinePlayers())
if (e.shouldSendTo(ChromaGamerBase.getFromSender(p)))
if (e.shouldSendTo(p))
p.sendMessage(str);
Bukkit.getConsoleSender().sendMessage(str);
}
public static String getMessageString(Channel channel, ChromaGamerBase sender, String message) {
return "§c!§r[" + channel.displayName.get() + "] <" + sender.getName() + "> " + message;
public static String getMessageString(Channel channel, CommandSender sender, String message) {
return "§c!§r[" + channel.DisplayName.get() + "] <"
+ ChromaUtils.getDisplayName(sender) + "> " + message;
}
public static void sendChatMessage(Channel channel, ChromaGamerBase sender, String message, CommandSender to) {
public static void sendChatMessage(Channel channel, CommandSender sender, String message, CommandSender to) {
to.sendMessage(getMessageString(channel, sender, message));
}
}

View file

@ -21,7 +21,7 @@ import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.ButtonPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import com.earth2me.essentials.Essentials;
@ -38,7 +38,7 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
* If enabled, stores and displays the last 10 messages the player can see (public, their town chat etc.)
* Can be used with the Discord plugin so players can see some of the conversation they missed that's visible on Discord anyways.
*/
public IConfigData<Boolean> storeChatHistory = getIConfig().getData("storeChatHistory", true);
public ConfigData<Boolean> storeChatHistory = getIConfig().getData("storeChatHistory", true);
// Fired when plugin is first enabled
@Override
@ -53,7 +53,7 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
if (Bukkit.getPluginManager().isPluginEnabled("Towny"))
Component.registerComponent(this, new TownyComponent());
TBMCChatAPI.registerChatChannel(new Channel("§7RP§f", Color.Gray, "rp", null)); //Since it's null, it's recognised as global
TBMCChatAPI.RegisterChatChannel(new Channel("§7RP§f", Color.Gray, "rp", null)); //Since it's null, it's recognised as global
if (!setupPermissions())
TBMCCoreAPI.SendException("We're in trouble", new Exception("Failed to set up permissions!"), this);

View file

@ -2,7 +2,6 @@ package buttondevteam.chat;
import buttondevteam.core.MainPlugin;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.player.ChromaGamerBase;
import lombok.experimental.UtilityClass;
import lombok.val;
import org.bukkit.entity.Player;
@ -17,12 +16,14 @@ import java.util.function.Predicate;
public class VanillaUtils {
public String getGroupIfChatOn(Player p, TBMCChatEvent e) {
try {
if (!isChatOn(p)) // Only send if client allows chat
if (isChatOn(p)) // Only send if client allows chat
return e.getGroupID(p);
else
return null;
} catch (NoClassDefFoundError ex) {
MainPlugin.getInstance().getLogger().warning("Compatibility error, can't check if the chat is hidden by the player.");
MainPlugin.Instance.getLogger().warning("Compatibility error, can't check if the chat is hidden by the player.");
return e.getGroupID(p);
}
return e.getGroupID(ChromaGamerBase.getFromSender(p));
}
private Predicate<Player> isChatOn;

View file

@ -1,5 +1,6 @@
package buttondevteam.chat.commands;
import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.*;
@ -10,6 +11,6 @@ import buttondevteam.lib.chat.*;
public class MeCommand extends ICommand2MC {
@Command2.Subcommand
public void def(Command2MCSender sender, @Command2.TextArg String message) {
TBMCChatAPI.SendSystemMessage(sender.getChannel(), sender.getChannel().getRTR(sender.getPermCheck()), "§5* " + sender.getSender().getName() + " " + message, TBMCSystemChatEvent.BroadcastTarget.ALL);
TBMCChatAPI.SendSystemMessage(sender.getChannel(), sender.getChannel().getRTR(sender.getPermCheck()), "§5* " + ChromaUtils.getDisplayName(sender.getSender()) + " " + message, TBMCSystemChatEvent.BroadcastTarget.ALL);
}
}

View file

@ -49,8 +49,8 @@ public final class HelpCommand extends UCommandBase {
"§nunderline - &n§r | §oitalic - &o§r", //
"The format codes in tellraw should be used like \"italic\":\"true\""}); //
} else {
String[] text = getManager().getCommandNode(topicOrCommand).getData().getHelpText(sender); // TODO: This only works for the main command, not subcommands
if (text == null) // TODO: Null check for command node
String[] text = getManager().getHelpText(topicOrCommand);
if (text == null)
sender.sendMessage(
new String[]{"§cError: Command not found: " + topicOrCommand,
"Usage example: /u accept --> /u help u accept"});

View file

@ -6,8 +6,9 @@ import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.CustomTabCompleteMethod;
import buttondevteam.lib.player.ChromaGamerBase;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.bukkit.command.CommandSender;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@ -25,22 +26,22 @@ public class HistoryCommand extends UCommandBase {
private static final HashMap<String, LinkedList<HistoryEntry>> messages = new HashMap<>();
@Command2.Subcommand
public boolean def(ChromaGamerBase sender, @Command2.OptionalArg String channel) {
public boolean def(CommandSender sender, @Command2.OptionalArg String channel) {
return showHistory(sender, channel);
}
public static boolean showHistory(ChromaGamerBase sender, String channel) {
public static boolean showHistory(CommandSender sender, String channel) {
if (!PluginMain.Instance.storeChatHistory.get()) {
sender.sendMessage("§6Chat history is disabled");
return true;
}
Function<Channel, LinkedList<HistoryEntry>> getThem = ch -> messages.get(ch.getIdentifier() + "_" + ch.getGroupID(sender)); //If can't see, groupID is null, and that shouldn't be in the map
Function<Channel, LinkedList<HistoryEntry>> getThem = ch -> messages.get(ch.ID + "_" + ch.getGroupID(sender)); //If can't see, groupID is null, and that shouldn't be in the map
sender.sendMessage("§6---- Chat History ----");
Stream<Channel> stream;
if (channel == null) {
stream = Channel.getChannels();
} else {
Optional<Channel> och = Channel.getChannels().filter(chan -> chan.getIdentifier().equalsIgnoreCase(channel)).findAny();
Optional<Channel> och = Channel.getChannels().filter(chan -> chan.ID.equalsIgnoreCase(channel)).findAny();
if (!och.isPresent()) {
sender.sendMessage("§cChannel not found. Use the ID, for example: /u history g");
return true;
@ -54,7 +55,7 @@ public class HistoryCommand extends UCommandBase {
for (int i = Math.max(0, arr.length - 10); i < arr.length; i++) {
HistoryEntry e = arr[i];
val cm = e.chatMessage;
sender.sendMessage("[" + e.channel.displayName.get() + "] " + cm.getUser().getName() + ": " + cm.getMessage());
sender.sendMessage("[" + e.channel.DisplayName.get() + "] " + cm.getSender().getName() + ": " + cm.getMessage());
sent.set(true);
}
}
@ -65,13 +66,17 @@ public class HistoryCommand extends UCommandBase {
@CustomTabCompleteMethod(param = "channel")
public Iterable<String> def() {
return Channel.getChannels().map(Channel::getIdentifier)::iterator;
return Channel.getChannels().map(ch -> ch.ID)::iterator;
}
/**
* @param timestamp System.nanoTime()
*/
private record HistoryEntry(long timestamp, ChatMessage chatMessage, Channel channel) {
@RequiredArgsConstructor
private static class HistoryEntry {
/**
* System.nanoTime()
*/
private final long timestamp;
private final ChatMessage chatMessage;
private final Channel channel;
}
public static void addChatMessage(ChatMessage chatMessage, Channel channel) {
@ -79,7 +84,7 @@ public class HistoryCommand extends UCommandBase {
val groupID = channel.getGroupID(chatMessage.getPermCheck());
if (groupID == null) return; //Just to be sure
synchronized (messages) {
var ll = messages.computeIfAbsent(channel.getIdentifier() + "_" + groupID, k -> new LinkedList<>()); //<-- TIL
var ll = messages.computeIfAbsent(channel.ID + "_" + groupID, k -> new LinkedList<>()); //<-- TIL
ll.add(new HistoryEntry(System.nanoTime(), chatMessage, channel)); //Adds as last element
while (ll.size() > 10)
ll.remove(); //Removes the first element

View file

@ -1,7 +1,10 @@
package buttondevteam.chat.components.announce;
import buttondevteam.chat.commands.ucmds.UCommandBase;
import buttondevteam.chat.components.formatter.ChatProcessing;
import buttondevteam.chat.components.formatter.FormatterComponent;
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
@ -10,12 +13,6 @@ import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.event.ClickEvent.Action.SUGGEST_COMMAND;
import static net.kyori.adventure.text.event.ClickEvent.clickEvent;
import static net.kyori.adventure.text.event.HoverEvent.Action.SHOW_TEXT;
import static net.kyori.adventure.text.event.HoverEvent.hoverEvent;
@CommandClass(modOnly = true)
@RequiredArgsConstructor
public class AnnounceCommand extends UCommandBase {
@ -63,9 +60,11 @@ public class AnnounceCommand extends UCommandBase {
sender.sendMessage(msg);
continue;
}
sender.sendMessage(text(msg)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Click to edit")))
.clickEvent(clickEvent(SUGGEST_COMMAND, "/" + getCommandPath() + " edit " + (i - 1) + " " + message.replace('§', '&'))));
String json = ChatProcessing.toJson(new TellrawPart(msg)
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Click to edit"))
.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND,
"/" + getCommandPath() + " edit " + (i - 1) + " " + message.replace('§', '&'))));
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json);
}
sender.sendMessage("§bCurrent wait time between announcements: "
+ component.announceTime.get() / 60 / 1000 + " minute(s)§r");

View file

@ -5,13 +5,11 @@ import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ComponentMetadata;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.config.IListConfigData;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.architecture.ListConfigData;
import buttondevteam.lib.chat.TBMCChatAPI;
import org.bukkit.Bukkit;
import java.util.Collections;
/**
* Displays the configured messages at the set interval when someone is online.
*/
@ -20,12 +18,12 @@ public class AnnouncerComponent extends Component<PluginMain> implements Runnabl
/**
* The messages to display to players.
*/
public IListConfigData<String> announceMessages = getConfig().getListData("announceMessages", Collections.emptyList());
public ListConfigData<String> announceMessages = getConfig().getListData("announceMessages");
/**
* The time in milliseconds between the messages. Use /u announce settime to set minutes.
*/
public IConfigData<Integer> announceTime = getConfig().getData("announceTime", 15 * 60 * 1000);
public ConfigData<Integer> announceTime = getConfig().getData("announceTime", 15 * 60 * 1000);
private TBMCSystemChatEvent.BroadcastTarget target;
@ -41,7 +39,7 @@ public class AnnouncerComponent extends Component<PluginMain> implements Runnabl
}
if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on
if (announceMessages.get().size() > AnnounceMessageIndex) {
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, announceMessages.get().get(AnnounceMessageIndex), target);
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, announceMessages.get().get(AnnounceMessageIndex), target);
AnnounceMessageIndex++;
if (AnnounceMessageIndex == announceMessages.get().size())
AnnounceMessageIndex = 0;

View file

@ -2,9 +2,10 @@ package buttondevteam.chat.components.appendext;
import buttondevteam.chat.PluginMain;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.architecture.IHaveConfig;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.chat.*;
import buttondevteam.lib.player.ChromaGamerBase;
import lombok.val;
import java.lang.reflect.Method;
@ -19,16 +20,16 @@ import java.util.function.Consumer;
public class AppendTextComponent extends Component<PluginMain> {
private Map<String, IHaveConfig> appendTexts;
private IConfigData<String[]> helpText(IHaveConfig config) {
return config.getData("helpText", new String[]{
private ConfigData<String[]> helpText(IHaveConfig config) {
return config.getData("helpText", () -> new String[]{
"Tableflip", //
"This command appends a tableflip after your message", //
"Or just makes you tableflip", //
});
}
private IConfigData<String> appendedText(IHaveConfig config) {
return config.getData("appendedText", "tableflip");
private ConfigData<String> appendedText(IHaveConfig config) {
return config.getData("appendedText", () -> "tableflip");
}
@Override
@ -100,7 +101,7 @@ public class AppendTextComponent extends Component<PluginMain> {
@Command2.Subcommand
public void def(Command2MCSender sender, @Command2.OptionalArg @Command2.TextArg String message) {
TBMCChatAPI.sendChatMessage(ChatMessage.builder(sender.getSender(),
TBMCChatAPI.SendChatMessage(ChatMessage.builder(sender.getSender(), ChromaGamerBase.getFromSender(sender.getSender()),
(message == null ? "" : message + " ") + appendedText).fromCommand(true).permCheck(sender.getPermCheck()).build());
}

View file

@ -2,12 +2,13 @@ package buttondevteam.chat.components.chatonly;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ComponentMetadata;
import buttondevteam.lib.player.TBMCPlayer;
import lombok.val;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.GameMode;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -16,10 +17,6 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.event.HoverEvent.Action.SHOW_TEXT;
import static net.kyori.adventure.text.event.HoverEvent.hoverEvent;
/**
* Allows players to enter chat-only mode which puts them into spectator mode and disallows moving.
*/
@ -46,11 +43,12 @@ public class ChatOnlyComponent extends Component<PluginMain> implements Listener
}
}
public static void tellrawCreate(ChatPlayer mp, TextComponent.Builder json) {
public static void tellrawCreate(ChatPlayer mp, TellrawPart json) {
if (!ComponentManager.isEnabled(ChatOnlyComponent.class))
return;
if (mp != null && mp.ChatOnly) {
json.append(text("[C]").hoverEvent(hoverEvent(SHOW_TEXT, text("Chat only"))));
json.addExtra(new TellrawPart("[C]")
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only")));
}
}

View file

@ -5,7 +5,7 @@ import buttondevteam.chat.PluginMain;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ComponentMetadata;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@ -27,7 +27,7 @@ public class FlairComponent extends Component<PluginMain> {
/**
* The Reddit thread to check for account connections. Re-enable the component if this was empty.
*/
IConfigData<String> flairThreadURL = getConfig().getData("flairThreadURL", "");
ConfigData<String> flairThreadURL = getConfig().getData("flairThreadURL", "");
/**
* <p>
@ -145,7 +145,7 @@ public class FlairComponent extends Component<PluginMain> {
} catch (Exception e) {
p.FlairState.set(FlairStates.Commented); // Flair unknown
p.SetFlair(ChatPlayer.FlairTimeNone);
TBMCCoreAPI.SendException("Error while checking join date for player " + p.getPlayerName() + "!", e, this);
TBMCCoreAPI.SendException("Error while checking join date for player " + p.PlayerName + "!", e, this);
}
return;
default:
@ -178,7 +178,7 @@ public class FlairComponent extends Component<PluginMain> {
}
public static void ConfirmUserMessage(ChatPlayer mp) {
Player p = Bukkit.getPlayer(mp.getUniqueId());
Player p = Bukkit.getPlayer(mp.getUUID());
if (mp.FlairState.get().equals(FlairStates.Commented) && p != null)
if (mp.UserNames.get().size() > 1)
p.sendMessage(

View file

@ -49,7 +49,8 @@ public class SetFlairCommand extends AdminCommandBase {
if (!mp.UserNames.get().contains(username))
mp.UserNames.get().add(username);
}
sender.sendMessage("§bThe flair has been set. Player: " + mp.getPlayerName() + " Flair: " + mp.GetFormattedFlair() + "§r");
sender.sendMessage(
"§bThe flair has been set. Player: " + mp.PlayerName + " Flair: " + mp.GetFormattedFlair() + "§r");
return true;
}

View file

@ -12,22 +12,20 @@ import buttondevteam.chat.components.towny.TownyComponent;
import buttondevteam.chat.listener.PlayerListener;
import buttondevteam.core.ComponentManager;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TellrawSerializableEnum;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.User;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.val;
import net.ess3.api.events.AfkStatusChangeEvent;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
@ -40,18 +38,12 @@ import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.event.ClickEvent.suggestCommand;
import static net.kyori.adventure.text.event.HoverEvent.Action.SHOW_TEXT;
import static net.kyori.adventure.text.event.HoverEvent.hoverEvent;
import static net.kyori.adventure.text.format.NamedTextColor.*;
public class ChatProcessing {
private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)");
private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),&]+(?:#[\\w]+)?)");
private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]]+)]\\(([^()]+)\\)");
private static final NamedTextColor[] RainbowPresserColors = new NamedTextColor[]{RED, GOLD, YELLOW, GREEN,
BLUE, DARK_PURPLE};
private static final Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green,
Color.Blue, Color.DarkPurple};
private static final Pattern WORD_PATTERN = Pattern.compile("\\S+");
private static final Pattern GREENTEXT_PATTERN = Pattern.compile("^>(?:.|\\s)*");
private static boolean pingedconsole = false;
@ -67,8 +59,8 @@ public class ChatProcessing {
cf.setHoverText(match);
return match;
}).build()),
new StringMatchProvider("nullMention", FormatSettings.builder().color(DARK_RED).build(), true, "null"), // Properly added a bug as a feature
new StringMatchProvider("consolePing", FormatSettings.builder().color(AQUA)
new StringMatchProvider("nullMention", FormatSettings.builder().color(Color.DarkRed).build(), true, "null"), // Properly added a bug as a feature
new StringMatchProvider("consolePing", FormatSettings.builder().color(Color.Aqua)
.onmatch((match, builder, section) -> {
if (!pingedconsole) {
System.out.print("\007");
@ -77,8 +69,8 @@ public class ChatProcessing {
return "@console";
}).build(), true, "@console"),
new StringMatchProvider("cyan", FormatSettings.builder().color(AQUA).build(), true, "cyan"), // #55
new RangeMatchProvider("code", "`", FormatSettings.builder().color(DARK_GRAY).build()),
new StringMatchProvider("cyan", FormatSettings.builder().color(Color.Aqua).build(), true, "cyan"), // #55
new RangeMatchProvider("code", "`", FormatSettings.builder().color(Color.DarkGray).build()),
new RegexMatchProvider("maskedLink", MASKED_LINK_PATTERN, FormatSettings.builder().underlined(true)
.onmatch((match, builder, section) -> {
String text, link;
@ -88,8 +80,8 @@ public class ChatProcessing {
return text;
}).build()),
new RegexMatchProvider("url", URL_PATTERN, FormatSettings.builder().underlined(true).openlink("$1").build()),
new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(BLUE).openlink("https://twitter.com/hashtag/$1").build()),
new StringMatchProvider("someone", FormatSettings.builder().color(AQUA)
new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(Color.Blue).openlink("https://twitter.com/hashtag/$1").build()),
new StringMatchProvider("someone", FormatSettings.builder().color(Color.Aqua)
.onmatch((match, builder, section) -> {
if (Bukkit.getOnlinePlayers().size() == 0) return match;
var players = ImmutableList.copyOf(Bukkit.getOnlinePlayers());
@ -98,7 +90,12 @@ public class ChatProcessing {
playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class));
return "@someone (" + player.getDisplayName() + "§r)";
}).build(), true, "@someone"),
new RegexMatchProvider("greentext", GREENTEXT_PATTERN, FormatSettings.builder().color(GREEN).build()));
new RegexMatchProvider("greentext", GREENTEXT_PATTERN, FormatSettings.builder().color(Color.Green).build()));
private static final Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum())
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
.registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool())
.registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create();
private static final String[] testPlayers = {"Koiiev", "iie", "Alisolarflare", "NorbiPeti", "Arsen_Derby_FTW", "carrot_lynx"};
private ChatProcessing() {
@ -106,14 +103,14 @@ public class ChatProcessing {
public static boolean ProcessChat(TBMCChatEvent e, FormatterComponent component) {
Channel channel = e.getChannel();
ChromaGamerBase cuser = e.getUser();
CommandSender sender = e.getSender();
String message = e.getMessage();
long processstart = System.nanoTime();
Player player = (cuser instanceof TBMCPlayerBase ? ((TBMCPlayerBase) cuser).getPlayer() : null);
Player player = (sender instanceof Player ? (Player) sender : null);
User user = PluginMain.essentials.getUser(player);
if (player != null && PluginMain.essentials.getSettings().cancelAfkOnInteract()) {
user.updateActivity(true, AfkStatusChangeEvent.Cause.CHAT); //Could talk in a private channel, so broadcast
user.updateActivity(true); //Could talk in a private channel, so broadcast
if (user.isMuted())
return true;
}
@ -126,7 +123,7 @@ public class ChatProcessing {
if (mp != null) {
if (System.nanoTime() - mp.LastMessageTime < 1000L * 1000L * component.minTimeBetweenMessages.get()) { //0.1s by default
cuser.sendMessage("§cYou are sending messages too quickly!");
sender.sendMessage("§cYou are sending messages too quickly!");
return true;
}
mp.LastMessageTime = System.nanoTime();
@ -138,48 +135,52 @@ public class ChatProcessing {
//IRegistry
//CraftServer
doFunStuff(cuser, e, message);
doFunStuff(sender, e, message);
final String channelidentifier = getChannelID(channel, e.getOrigin());
PluginMain.Instance.getServer().getConsoleSender()
.sendMessage(String.format("%s <%s§r> %s", channelidentifier, cuser.getName(), message));
.sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message));
if (Bukkit.getOnlinePlayers().size() == 0) return false; //Don't try to send to nobody (errors on 1.14)
TextColor colormode = NAMES.value(channel.color.get().getName());
boolean colorModeChanged = false;
if (mp != null && mp.OtherColorMode != null) {
colormode = NAMES.value(mp.OtherColorMode.getName());
colorModeChanged = true;
}
Color colormode = channel.Color.get();
if (mp != null && mp.OtherColorMode != null)
colormode = mp.OtherColorMode;
ArrayList<MatchProviderBase> formatters;
if (component.allowFormatting.get()) {
formatters = addFormatters(sender -> e.shouldSendTo(ChromaGamerBase.getFromSender(sender)), component);
if (colorModeChanged && mp.RainbowPresserColorMode) { // Only overwrite channel color
formatters = addFormatters(e::shouldSendTo, component);
if (colormode == channel.Color.get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
createRPC(colormode, formatters);
}
pingedconsole = false; // Will set it to true onmatch (static constructor)
} else
formatters = Lists.newArrayList();
TextComponent.Builder builder = createEmptyMessageLine(cuser, message, player, channelidentifier, e.getOrigin());
TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin());
long combinetime = System.nanoTime();
ChatFormatter.Combine(formatters, message, builder, component.getConfig(), FormatSettings.builder().color(colormode).build());
ChatFormatter.Combine(formatters, message, json, component.getConfig(), FormatSettings.builder().color(colormode).build());
combinetime = System.nanoTime() - combinetime;
String jsonstr = toJson(json);
if (jsonstr.length() >= 32767) {
sender.sendMessage(
"§cError: Message too long. Try shortening it, or remove hashtags and other formatting.");
return true;
}
DebugCommand.SendDebugMessage(jsonstr);
try {
if (!channel.isGlobal()) {
String senderGroup = e.getGroupID(cuser);
String senderGroup = e.getGroupID(sender);
if (senderGroup == null) { // Never send messages if the group is null
cuser.sendMessage("§cYou don't have permission to send this message or something went wrong");
sender.sendMessage("§cYou don't have permission to send this message or something went wrong");
return true;
}
val tc = ComponentManager.getIfEnabled(TownyComponent.class);
Consumer<Player> spyConsumer = null;
if (tc != null)
spyConsumer = tc.handleSpiesInit(channel, builder);
spyConsumer = tc.handleSpiesInit(channel, json, ChatProcessing::toJson, sender, message);
for (Player p : Bukkit.getOnlinePlayers()) {
final String group;
if (player != null
@ -187,18 +188,19 @@ public class ChatProcessing {
group = null; // Don't send the message to them
else
group = VanillaUtils.getGroupIfChatOn(p, e);
if (senderGroup.equals(group)) {
p.sendMessage(builder.build());
if (tc != null) spyConsumer.accept(p);
}
if (senderGroup.equals(group))
if (!VanillaUtils.tellRaw(p, jsonstr))
p.sendMessage(ChatUtils.getMessageString(channel, sender, message));
else if (tc != null) spyConsumer.accept(p);
//Only sends if didn't send normally
}
} else
for (Player p : Bukkit.getOnlinePlayers())
p.sendMessage(builder.build());
if (!VanillaUtils.tellRaw(p, jsonstr))
ChatUtils.sendChatMessage(channel, sender, message, p);
} catch (Exception ex) {
TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex, PluginMain.Instance);
cuser.sendMessage("§cAn error occured while sending the message.");
sender.sendMessage("§cAn error occured while sending the message.");
return true;
}
DebugCommand.SendDebugMessage(
@ -207,7 +209,7 @@ public class ChatProcessing {
return false;
}
static void createRPC(TextColor colormode, ArrayList<MatchProviderBase> formatters) {
static void createRPC(Color colormode, ArrayList<MatchProviderBase> formatters) {
final AtomicInteger rpc = new AtomicInteger(0);
formatters.add(new RegexMatchProvider("rpc", WORD_PATTERN, FormatSettings.builder().color(colormode).onmatch((match, cf, s) -> {
cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
@ -215,29 +217,46 @@ public class ChatProcessing {
}).build()));
}
static TextComponent.Builder createEmptyMessageLine(ChromaGamerBase user, String message, @Nullable Player player,
final String channelidentifier, String origin) {
val json = text();
ChatOnlyComponent.tellrawCreate(user.getAs(ChatPlayer.class), json);
val channelHover = (ChatUtils.MCORIGIN.equals(origin) ? "" : "From " + origin + "\n") + "Copy message";
json.append(text(channelidentifier)
.hoverEvent(hoverEvent(SHOW_TEXT, text(channelHover).color(BLUE))).clickEvent(suggestCommand(message)));
if (player != null) {
if (PluginMain.permission.has(player, "tbmc.badge.diamond")) // TODO: Cross-platform permissions
json.append(text("[P]").color(AQUA).decorate(TextDecoration.BOLD)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Diamond Patreon supporter"))));
else if (PluginMain.permission.has(player, "tbmc.badge.gold"))
json.append(text("[P]").color(GOLD).decorate(TextDecoration.BOLD)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Gold Patreon supporter"))));
}
json.append(text(" <"));
json.append(text(user.getName()).hoverEvent(hoverEvent(SHOW_TEXT, text(user.getInfo(ChromaGamerBase.InfoTarget.MCHover)))));
json.append(text("> "));
public static String toJson(TellrawPart json) {
return gson.toJson(json);
}
static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player,
@Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier,
String origin) {
TellrawPart json = new TellrawPart("");
ChatOnlyComponent.tellrawCreate(mp, json); //TODO: Make nice API
json.addExtra(
new TellrawPart(channelidentifier)
.setHoverEvent(
TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
new TellrawPart((ChatUtils.MCORIGIN.equals(origin) ? "" : "From " + origin + "\n")
+ "Copy message").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message)));
if (PluginMain.permission.has(sender, "tbmc.badge.diamond"))
json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true)
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter")));
else if (PluginMain.permission.has(sender, "tbmc.badge.gold"))
json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true)
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter")));
json.addExtra(new TellrawPart(" <"));
TellrawPart hovertp = new TellrawPart("");
if (cg != null)
hovertp.addExtra(new TellrawPart(cg.getInfo(ChromaGamerBase.InfoTarget.MCHover)));
json.addExtra(new TellrawPart(getSenderName(sender, player))
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp)));
json.addExtra(new TellrawPart("> "));
return json;
}
private static String getSenderName(CommandSender sender, Player player) {
if (player == null)
return sender.getName();
return player.getDisplayName();
}
static String getChannelID(Channel channel, String origin) {
return ("[" + (ChatUtils.MCORIGIN.equals(origin) ? "" : "§8" + origin.charAt(0) + "§r|") + channel.displayName.get())
return ("[" + (ChatUtils.MCORIGIN.equals(origin) ? "" : "§8" + origin.charAt(0) + "§r|") + channel.DisplayName.get())
+ "]";
}
@ -246,7 +265,7 @@ public class ChatProcessing {
ArrayList<MatchProviderBase> formatters = (ArrayList<MatchProviderBase>) commonFormatters.clone();
boolean nottest; //Not assigning a default value, so that it can only be used in the if
if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || ChromaUtils.isTest()) {
if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) {
String[] names;
if (nottest)
names = Bukkit.getOnlinePlayers().stream().filter(canSee).map(CommandSender::getName).toArray(String[]::new);
@ -265,12 +284,12 @@ public class ChatProcessing {
};
if (names.length > 0) //Add as first so it handles special characters (_) - though the order of the different types are defined
formatters.add(0, new StringMatchProvider("name", FormatSettings.builder().color(AQUA)
formatters.add(0, new StringMatchProvider("name", FormatSettings.builder().color(Color.Aqua)
.onmatch((match, builder, section) -> {
Player p = Bukkit.getPlayer(match);
Optional<String> pn = nottest ? Optional.empty()
: Arrays.stream(testPlayers).filter(tp -> tp.equalsIgnoreCase(match)).findAny();
if (nottest ? p == null : pn.isEmpty()) {
if (nottest ? p == null : !pn.isPresent()) {
error.accept("Error: Can't find player " + match + " but was reported as online.");
return "§c" + match + "§r";
}
@ -283,7 +302,7 @@ public class ChatProcessing {
}).build(), true, names));
if (nicknames.length > 0) //Add as first so it handles special characters
formatters.add(0, new StringMatchProvider("nickname", FormatSettings.builder().color(AQUA)
formatters.add(0, new StringMatchProvider("nickname", FormatSettings.builder().color(Color.Aqua)
.onmatch((match, builder, section) -> {
if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased
Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase()));
@ -311,8 +330,8 @@ public class ChatProcessing {
component.notificationPitch.get());
}
static void doFunStuff(ChromaGamerBase user, TBMCChatEventBase event, String message) {
static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
val fc = ComponentManager.getIfEnabled(FunComponent.class);
if (fc != null) fc.onChat(user, event, message);
if (fc != null) fc.onChat(sender, event, message);
}
}

View file

@ -5,7 +5,7 @@ import buttondevteam.core.ComponentManager;
import buttondevteam.core.MainPlugin;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.ConfigData;
/**
* This component handles the custom processing of chat messages. If this component is disabled channels won't be supported in Minecraft.
@ -16,31 +16,31 @@ public class FormatterComponent extends Component<PluginMain> {
/**
* Determines whether Markdown formatting, name mentioning and similar features are enabled.
*/
IConfigData<Boolean> allowFormatting = getConfig().getData("allowFormatting", true);
ConfigData<Boolean> allowFormatting = getConfig().getData("allowFormatting", true);
/**
* The sound to play when a player is mentioned. Leave empty to use default.
*/
public IConfigData<String> notificationSound = getConfig().getData("notificationSound", "");
public ConfigData<String> notificationSound = getConfig().getData("notificationSound", "");
/**
* The pitch of the notification sound.
*/
public IConfigData<Float> notificationPitch = getConfig().getData("notificationPitch", 1.0f);
public ConfigData<Float> notificationPitch = getConfig().getData("notificationPitch", 1.0f);
/**
* The minimum time between messages in milliseconds.
*/
public IConfigData<Integer> minTimeBetweenMessages = getConfig().getData("minTimeBetweenMessages", 100);
public ConfigData<Integer> minTimeBetweenMessages = getConfig().getData("minTimeBetweenMessages", 100);
@Override
protected void enable() {
MainPlugin.getInstance().setChatHandlerEnabled(false); //Disable Core chat handler - if this component is disabled then let it do its job
MainPlugin.Instance.setChatHandlerEnabled(false); //Disable Core chat handler - if this component is disabled then let it do its job
}
@Override
protected void disable() {
MainPlugin.getInstance().setChatHandlerEnabled(true);
MainPlugin.Instance.setChatHandlerEnabled(true);
}
/**

View file

@ -2,24 +2,15 @@ package buttondevteam.chat.components.formatter.formatting;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import buttondevteam.lib.architecture.IHaveConfig;
import buttondevteam.lib.chat.Color;
import lombok.val;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.event.ClickEvent.Action.OPEN_URL;
import static net.kyori.adventure.text.event.ClickEvent.clickEvent;
import static net.kyori.adventure.text.event.HoverEvent.Action.SHOW_TEXT;
import static net.kyori.adventure.text.event.HoverEvent.hoverEvent;
/**
* A {@link MatchProvider} finds where the given {@link FormatSettings} need to be applied. {@link ChatFormatter#Combine(List, String, TextComponent.Builder, IHaveConfig, FormatSettings)}} is used to turn it into a {@link TellrawPart}, combining
* A {@link MatchProvider} finds where the given {@link FormatSettings} need to be applied. {@link ChatFormatter#Combine(List, String, TellrawPart, IHaveConfig, FormatSettings)}} is used to turn it into a {@link TellrawPart}, combining
* intersecting parts found, for example when {@code _abc*def*ghi_} is said in chat, it'll turn it into an underlined part, then an underlined <i>and italics</i> part, finally an underlined part
* again.
*
@ -35,7 +26,7 @@ public final class ChatFormatter {
}
//synchronized: Some of the formatters are reused, see createSections(...)
public static synchronized void Combine(List<MatchProviderBase> formatters, String str, TextComponent.Builder tp, IHaveConfig config, FormatSettings defaults) {
public static synchronized void Combine(List<MatchProviderBase> formatters, String str, TellrawPart tp, IHaveConfig config, FormatSettings defaults) {
/*
* A global formatter is no longer needed
*/
@ -161,11 +152,11 @@ public final class ChatFormatter {
DebugCommand.SendDebugMessage("To sections");
if (!removeIfNeeded.test(firstSection)) {
DebugCommand.SendDebugMessage(" 1:" + firstSection);
DebugCommand.SendDebugMessage(" 1:" + firstSection + "");
ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End);
}
if (!removeIfNeeded.test(section)) {
DebugCommand.SendDebugMessage(" 2:" + section);
DebugCommand.SendDebugMessage(" 2:" + section + "");
ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End);
}
if (!removeIfNeeded.test(lastSection)) {
@ -178,8 +169,8 @@ public final class ChatFormatter {
}
}
private static void applySections(String str, TextComponent.Builder tp, ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
TextComponent lasttp = null;
private static void applySections(String str, TellrawPart tp, ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
TellrawPart lasttp = null;
String lastlink = null;
for (FormattedSection section : sections) {
DebugCommand.SendDebugMessage("Applying section: " + section);
@ -187,9 +178,21 @@ public final class ChatFormatter {
int start = section.Start, end = section.End;
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
ChatFormatUtils.sendMessageWithPointer(str, start, end);
/*DebugCommand.SendDebugMessage("RCS: "+remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).count());
DebugCommand.SendDebugMessage("RCE: "+remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).count());
DebugCommand.SendDebugMessage("RCI: "+remchars.stream().filter(rc -> start < rc[0] || rc[1] < end).count());*/
val rci = remchars.stream().filter(rc -> (rc[0] <= start && rc[1] >= start)
|| (rc[0] >= start && rc[1] <= end)
|| (rc[0] <= end && rc[1] >= end)).sorted(Comparator.comparingInt(rc -> rc[0] * 10000 + rc[1])).toArray(int[][]::new);
/*if (rcs.isPresent())
s = rcs.get()[1] + 1;
if (rce.isPresent())
e = rce.get()[0] - 1;
DebugCommand.SendDebugMessage("After RC - Start: " + s + " - End: " + e);
if (e - s < 0) { //e-s==0 means the end char is the same as start char, so one char message
DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")");
continue;
}*/
DebugCommand.SendDebugMessage("Applying RC: " + Arrays.stream(rci).map(Arrays::toString).collect(Collectors.joining(", ", "[", "]")));
originaltext = str.substring(start, end + 1);
val sb = new StringBuilder(originaltext);
@ -202,53 +205,50 @@ public final class ChatFormatter {
}
DebugCommand.SendDebugMessage("Section text: " + originaltext);
String openlink = null;
//section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
TellrawPart newtp = new TellrawPart("");
var settings = section.Settings;
DebugCommand.SendDebugMessage("Applying settings: " + settings);
if (lasttp != null && hasSameDecorations(lasttp, settings) && Objects.equals(lastlink, settings.openlink)
&& settings.onmatch == null) { // The onmatch function can change the settings
DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
lasttp = lasttp.content(lasttp.content() + originaltext);
continue; //Combine parts with the same properties
}
TextComponent.@NotNull Builder newtp = text();
if (settings.onmatch != null)
originaltext = settings.onmatch.apply(originaltext, settings, section);
if (settings.color != null)
newtp.color(settings.color);
newtp.setColor(settings.color);
if (settings.bold)
newtp.decorate(TextDecoration.BOLD);
newtp.setBold(true);
if (settings.italic)
newtp.decorate(TextDecoration.ITALIC);
newtp.setItalic(true);
if (settings.underlined)
newtp.decorate(TextDecoration.UNDERLINED);
newtp.setUnderlined(true);
if (settings.strikethrough)
newtp.decorate(TextDecoration.STRIKETHROUGH);
newtp.setStrikethrough(true);
if (settings.obfuscated)
newtp.decorate(TextDecoration.OBFUSCATED);
newtp.setObfuscated(true);
if (settings.openlink != null)
openlink = settings.openlink;
if (settings.hoverText != null)
newtp.hoverEvent(hoverEvent(SHOW_TEXT, text(settings.hoverText)));
if (lasttp != null) tp.append(lasttp);
lastlink = openlink;
newtp.content(originaltext);
if (openlink != null && openlink.length() > 0) {
if (section.Matches.size() > 0)
openlink = openlink.replace("$1", section.Matches.get(0));
newtp.clickEvent(clickEvent(OPEN_URL, openlink)).hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(NamedTextColor.BLUE)));
newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, settings.hoverText));
if (lasttp != null && newtp.getColor() == lasttp.getColor()
&& newtp.isBold() == lasttp.isBold()
&& newtp.isItalic() == lasttp.isItalic()
&& newtp.isUnderlined() == lasttp.isUnderlined()
&& newtp.isStrikethrough() == lasttp.isStrikethrough()
&& newtp.isObfuscated() == lasttp.isObfuscated()
&& Objects.equals(openlink, lastlink)) {
DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
lasttp.setText(lasttp.getText() + originaltext);
continue; //Combine parts with the same properties
}
lasttp = newtp.build();
lastlink = openlink;
newtp.setText(originaltext);
if (openlink != null && openlink.length() > 0) {
newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL,
(section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
new TellrawPart("Click to open").setColor(Color.Blue)));
}
tp.addExtra(newtp);
lasttp = newtp;
}
if (lasttp != null) tp.append(lasttp);
}
private static boolean hasSameDecorations(TextComponent c1, FormatSettings settings) {
return Objects.equals(c1.color(), settings.color)
&& c1.hasDecoration(TextDecoration.BOLD) == settings.bold
&& c1.hasDecoration(TextDecoration.ITALIC) == settings.italic
&& c1.hasDecoration(TextDecoration.UNDERLINED) == settings.underlined
&& c1.hasDecoration(TextDecoration.STRIKETHROUGH) == settings.strikethrough
&& c1.hasDecoration(TextDecoration.OBFUSCATED) == settings.obfuscated;
}
private static void sortSections(ArrayList<FormattedSection> sections) {

View file

@ -1,8 +1,8 @@
package buttondevteam.chat.components.formatter.formatting;
import buttondevteam.lib.chat.Color;
import lombok.Builder;
import lombok.Data;
import net.kyori.adventure.text.format.TextColor;
/**
* Describes how a matched section of the message should look. May be combined with other format settings.
@ -15,7 +15,7 @@ public class FormatSettings {
boolean underlined;
boolean strikethrough;
boolean obfuscated;
TextColor color;
Color color;
ChatFormatter.TriFunc<String, FormatSettings, FormattedSection, String> onmatch;
String openlink;
String hoverText;

View file

@ -1,7 +1,7 @@
package buttondevteam.chat.components.formatter.formatting;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.architecture.IHaveConfig;
import buttondevteam.lib.architecture.config.IConfigData;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@ -31,7 +31,7 @@ public abstract class MatchProviderBase implements MatchProvider {
resetSubclass();
}
IConfigData<Boolean> enabled(IHaveConfig config) {
ConfigData<Boolean> enabled(IHaveConfig config) {
return config.getData(name + ".enabled", true);
}

View file

@ -54,8 +54,8 @@ public class FTopCommand extends ICommand2MC {
}
val ai = new AtomicInteger();
sender.sendMessage("§6---- Top Fs ----");
sender.sendMessage(Arrays.stream(cached).skip((i - 1) * 10L).limit(i * 10L)
.map(cp -> String.format("%d. %s - %f.2", ai.incrementAndGet(), cp.getPlayerName(), cp.getF()))
sender.sendMessage(Arrays.stream(cached).skip((i - 1) * 10).limit(i * 10)
.map(cp -> String.format("%d. %s - %f.2", ai.incrementAndGet(), cp.PlayerName.get(), cp.getF()))
.collect(Collectors.joining("\n")));
});
return true;

View file

@ -3,19 +3,18 @@ package buttondevteam.chat.components.fun;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.PluginMain;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCCommandPreprocessEvent;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.config.IListConfigData;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.google.common.collect.Lists;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -37,7 +36,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
private boolean ActiveF = false;
private ChatPlayer FPlayer = null;
private BukkitTask Ftask = null;
private final HashSet<ChromaGamerBase> Fs = new HashSet<>();
private final HashSet<CommandSender> Fs = new HashSet<>();
private UnlolCommand command;
private TBMCSystemChatEvent.BroadcastTarget unlolTarget;
private TBMCSystemChatEvent.BroadcastTarget fTarget;
@ -46,20 +45,20 @@ public class FunComponent extends Component<PluginMain> implements Listener {
/**
* The strings that count as laughs, see unlol.
*/
private final IListConfigData<String> laughStrings = getConfig().getListData("laughStrings", Lists.newArrayList("xd", "lel", "lawl", "kek", "lmao", "hue", "hah", "rofl"));
private final ConfigData<String[]> laughStrings = getConfig().getData("laughStrings", () -> new String[]{"xd", "lel", "lawl", "kek", "lmao", "hue", "hah", "rofl"});
/**
* The "Press F to pay respects" meme in Minecraft. It will randomly appear on player death and keep track of how many "F"s are said in chat.
* You can hover over a player's name to see their respect.
*/
private final IConfigData<Boolean> respect = getConfig().getData("respect", true);
private final ConfigData<Boolean> respect = getConfig().getData("respect", true);
/**
* This is an inside joke on our server.
* It keeps track of laughs (lols and what's defined in laughStrings) and if someone does /unlol or /unlaugh it will unlaugh the last person who laughed.
* Which also blinds the laughing person for a few seconds. This action can only be performed once per laugh.
*/
private final IConfigData<Boolean> unlol = getConfig().getData("unlol", true);
private final ConfigData<Boolean> unlol = getConfig().getData("unlol", true);
@Override
protected void enable() {
@ -81,21 +80,20 @@ public class FunComponent extends Component<PluginMain> implements Listener {
}
public void onChat(ChromaGamerBase sender, TBMCChatEventBase event, String message) {
public void onChat(CommandSender sender, TBMCChatEventBase event, String message) {
if (ActiveF && !Fs.contains(sender) && message.equalsIgnoreCase("F"))
Fs.add(sender);
if (unlol.get()) {
String msg = message.toLowerCase();
val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime());
boolean add = msg.contains("lol");
if (add)
boolean add;
if (add = msg.contains("lol"))
lld.setLolornot(true);
else {
val laughs = laughStrings.get();
String[] laughs = laughStrings.get();
for (String laugh : laughs) {
add = msg.contains(laugh);
if (add) {
if (add = msg.contains(laugh)) {
lld.setLolornot(false);
break;
}
@ -115,7 +113,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
ActiveF = false;
if (FPlayer != null && FPlayer.FCount.get() < Integer.MAX_VALUE - 1)
FPlayer.FCount.set(FPlayer.FCount.get() + Fs.size());
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL,
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL,
"§b" + Fs.size() + " " + (Fs.size() == 1 ? "person" : "people")
+ " paid their respects.§r", fTarget);
Fs.clear();
@ -129,7 +127,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
Fs.clear();
FPlayer = TBMCPlayer.getPlayer(e.getEntity().getUniqueId(), ChatPlayer.class);
FPlayer.FDeaths.set(FPlayer.FDeaths.get() + 1);
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL,
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL,
"§bPress F to pay respects.§r", fTarget);
Ftask = Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.Instance, tt, 15 * 20);
}
@ -138,7 +136,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
@EventHandler
public void onPlayerLeave(PlayerQuitEvent event) {
if (unlol.get())
command.Lastlol.values().removeIf(lld -> lld.getLolowner().equals(ChromaGamerBase.getFromSender(event.getPlayer())));
command.Lastlol.values().removeIf(lld -> lld.getLolowner().equals(event.getPlayer()));
}
@EventHandler(priority = EventPriority.LOWEST)
@ -152,14 +150,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
if (ht.getName().equalsIgnoreCase(cmd))
return;
}
val user = event.getSender();
if (!(user instanceof TBMCPlayerBase)) {
// TODO: Cross-platform permission check; console is not supported here
user.sendMessage("§cError: You must be a player to use this command.");
return;
}
val player = ((TBMCPlayerBase) user).getPlayer();
if (player != null && PluginMain.permission.has(player, "chroma.unanything")) {
if (PluginMain.permission.has(event.getSender(), "chroma.unanything")) {
event.setCancelled(true);
int index = cmd.lastIndexOf(' ');
if (index == -1) {
@ -172,9 +163,10 @@ public class FunComponent extends Component<PluginMain> implements Listener {
event.getSender().sendMessage("§cError: Player not found. (/un" + s + " <player>)");
return;
}
val user = ChromaGamerBase.getFromSender(event.getSender());
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 10 * 20, 5, false, false));
val chan = user.getChannel().get();
TBMCChatAPI.SendSystemMessage(chan, chan.getRTR(event.getSender()), event.getSender().getName() + " un" + s
val chan = user.channel.get();
TBMCChatAPI.SendSystemMessage(chan, chan.getRTR(event.getSender()), ChromaUtils.getDisplayName(event.getSender()) + " un" + s
+ "'d " + target.getDisplayName(), unlolTarget);
}
}

View file

@ -1,7 +1,6 @@
package buttondevteam.chat.components.fun;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.core.component.restart.RestartComponent;
import buttondevteam.core.component.restart.ScheduledRestartCommand;
import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.ScheduledServerRestartEvent;
@ -37,7 +36,7 @@ public class PressCommand extends ICommand2MC implements Listener {
return;
}
pressers.add(sender);
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, String.format("§b-- %s §bpressed at %.0fs", ChromaUtils.getDisplayName(sender), command.getRestartCounter() / 20f), ((RestartComponent) command.getComponent()).getRestartBroadcast());
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("§b-- %s §bpressed at %.0fs", ChromaUtils.getDisplayName(sender), command.getRestartCounter() / 20f), command.getComponent().getRestartBroadcast());
command.setRestartCounter(startTicks);
}
@ -47,6 +46,6 @@ public class PressCommand extends ICommand2MC implements Listener {
pressers = new HashSet<>();
startTicks = event.getRestartTicks();
if (Bukkit.getOnlinePlayers().size() > 0)
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, "§b-- Do /press to reset the timer. You may only press once.", ((RestartComponent) command.getComponent()).getRestartBroadcast());
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, "§b-- Do /press to reset the timer. You may only press once.", command.getComponent().getRestartBroadcast());
}
}

View file

@ -1,16 +1,17 @@
package buttondevteam.chat.components.fun;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.ChromaUtils;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.ICommand2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayerBase;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@ -32,18 +33,18 @@ public final class UnlolCommand extends ICommand2MC {
private final TBMCSystemChatEvent.BroadcastTarget target;
@Command2.Subcommand
public boolean def(ChromaGamerBase sender) {
public boolean def(CommandSender sender) {
LastlolData lol = Lastlol.values().stream().filter(lld -> lld.Chatevent.shouldSendTo(sender))
.max(Comparator.comparingLong(lld -> lld.Loltime)).orElse(null);
.max(Comparator.comparingLong(lld -> lld.Loltime)).orElse(null);
if (lol == null)
return true;
if (lol.Lolowner instanceof TBMCPlayerBase) {
var player = ((TBMCPlayerBase) lol.Lolowner).getPlayer();
if (player != null)
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 2 * 20, 5, false, false));
}
String msg = sender.getName() + (lol.Lolornot ? " unlolled " : " unlaughed ") + lol.Lolowner.getName();
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, msg, target);
if (lol.Lolowner instanceof Player)
((Player) lol.Lolowner)
.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 2 * 20, 5, false, false));
String msg = ChromaUtils.getDisplayName(sender)
+ (lol.Lolornot ? " unlolled " : " unlaughed ")
+ ChromaUtils.getDisplayName(lol.Lolowner);
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, msg, target);
Lastlol.remove(lol.Chatevent.getChannel());
return true;
}
@ -51,7 +52,7 @@ public final class UnlolCommand extends ICommand2MC {
@Data
public static class LastlolData {
private boolean Lolornot;
private final ChromaGamerBase Lolowner;
private final CommandSender Lolowner;
private final TBMCChatEventBase Chatevent;
private final long Loltime;
}

View file

@ -8,7 +8,7 @@ import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ComponentMetadata;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.player.TBMCPlayer;
import com.earth2me.essentials.User;
@ -53,13 +53,13 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
/**
* The amount of town colors allowed. If more than one is used (or nation colors are enabled), players can change how many letters to be in a specific color using /u ncolor.
*/
public final IConfigData<Byte> colorCount = getConfig().getData("colorCount", (byte) 1, cc -> ((Integer) cc).byteValue(), Byte::intValue);
public final ConfigData<Byte> colorCount = getConfig().getData("colorCount", (byte) 1, cc -> ((Integer) cc).byteValue(), Byte::intValue);
/**
* If enabled, players will have a nation-defined color in addition to town colors, white by default.
* They can change how much of each color they want with this as well.
*/
public final IConfigData<Boolean> useNationColors = getConfig().getData("useNationColors", true);
public final ConfigData<Boolean> useNationColors = getConfig().getData("useNationColors", true);
@Getter
private static TownColorComponent component;
@ -84,9 +84,9 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
loadNC.accept(ncs);
}
TownColors.keySet().removeIf(t -> TownyComponent.dataSource.getTown(t) == null); // Removes town colors for deleted/renamed towns
TownColors.keySet().removeIf(t -> !TownyComponent.dataSource.hasTown(t)); // Removes town colors for deleted/renamed towns
if (usenc)
NationColor.keySet().removeIf(n -> TownyComponent.dataSource.getNation(n) == null); // Removes nation colors for deleted/renamed nations
NationColor.keySet().removeIf(n -> !TownyComponent.dataSource.hasNation(n)); // Removes nation colors for deleted/renamed nations
initDynmap();
@ -156,7 +156,12 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
if (nickname.contains("~")) //StartsWith doesn't work because of color codes
nickname = nickname.replace("~", ""); //It gets stacked otherwise
String name = ChatColor.stripColor(nickname); //Enforce "town colors" on non-members
Resident res = TownyComponent.dataSource.getResident(player.getName());
Resident res;
try {
res = TownyComponent.dataSource.getResident(player.getName());
} catch (NotRegisteredException e) {
return name;
}
if (res == null || !res.hasTown())
return name;
try {

View file

@ -9,6 +9,7 @@ import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.CustomTabCompleteMethod;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyObject;
@ -23,12 +24,13 @@ import org.bukkit.command.CommandSender;
public class NationColorCommand extends AdminCommandBase {
@Command2.Subcommand
public boolean def(CommandSender sender, String nation, String color) {
final Nation n = TownyComponent.dataSource.getNation(nation);
if (n == null) {
try {
final Nation n = TownyComponent.dataSource.getNation(nation);
return SetNationColor(sender, n, color);
} catch (NotRegisteredException e) {
sender.sendMessage("§cThe nation '" + nation + "' cannot be found.");
return true;
}
return SetNationColor(sender, n, color);
}
@CustomTabCompleteMethod(param = "color")

View file

@ -8,6 +8,7 @@ import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.CustomTabCompleteMethod;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyObject;
import lombok.val;
@ -28,16 +29,17 @@ import java.util.stream.Collectors;
public class TownColorCommand extends AdminCommandBase {
@Command2.Subcommand
public boolean def(CommandSender sender, String town, String... colornames) {
if (TownyComponent.dataSource.getTown(town) == null) {
if (!TownyComponent.dataSource.hasTown(town)) {
sender.sendMessage("§cThe town '" + town + "' cannot be found.");
return true;
}
Town targetTown = TownyComponent.dataSource.getTown(town);
if (targetTown == null) {
try {
Town targetTown = TownyComponent.dataSource.getTown(town);
return SetTownColor(sender, targetTown, colornames);
} catch (NotRegisteredException e) {
sender.sendMessage("§cThe town '" + town + "' cannot be found.");
return true;
}
return SetTownColor(sender, targetTown, colornames);
}
@CustomTabCompleteMethod(param = "colornames")
@ -116,11 +118,11 @@ public class TownColorCommand extends AdminCommandBase {
}
public static String getTownNameCased(String name) {
val town = TownyComponent.dataSource.getTown(name);
if (town == null) {
try {
return TownyComponent.dataSource.getTown(name).getName();
} catch (NotRegisteredException e) {
return null;
}
return town.getName();
}
public static Iterable<String> tabcompleteColor() {

View file

@ -44,7 +44,7 @@ public class TownyAnnouncer {
message, target, ChatUtils.MCORIGIN);
break;
case "Global":
TBMCChatAPI.SendSystemMessage(Channel.globalChat,
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat,
Channel.RecipientTestResult.ALL,
message, target, ChatUtils.MCORIGIN);
break;

View file

@ -1,24 +1,26 @@
package buttondevteam.chat.components.towny;
import buttondevteam.chat.ChatUtils;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.VanillaUtils;
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.db.TownyDataSource;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import lombok.val;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -27,7 +29,7 @@ import java.util.stream.Collectors;
* You can disable /tc and /nc in Chroma-Core's config if you only want to use the TownColorComponent.
*/
public class TownyComponent extends Component<PluginMain> {
public static TownyAPI dataSource;
public static TownyDataSource dataSource;
private static ArrayList<String> Towns;
private static ArrayList<String> Nations;
@ -36,12 +38,24 @@ public class TownyComponent extends Component<PluginMain> {
@Override
protected void enable() {
dataSource = TownyAPI.getInstance();
Towns = TownyUniverse.getInstance().getTowns().stream().map(Town::getName).collect(Collectors.toCollection(ArrayList::new)); // Creates a snapshot of towns, new towns will be added when needed
Nations = TownyUniverse.getInstance().getNations().stream().map(Nation::getName).collect(Collectors.toCollection(ArrayList::new)); // Same here but with nations
TBMCChatAPI.registerChatChannel(
try {
try {
var tucl = Class.forName("com.palmergames.bukkit.towny.TownyUniverse");
var tu = tucl.getMethod("getInstance").invoke(null);
dataSource = (TownyDataSource) tucl.getMethod("getDataSource")
.invoke(tu);
} catch (ClassNotFoundException e) {
dataSource = (TownyDataSource) Class.forName("com.palmergames.bukkit.towny.object.TownyUniverse").getMethod("getDataSource")
.invoke(null);
}
} catch (Exception e) {
throw new RuntimeException("Failed to find Towny's data source!", e);
}
Towns = dataSource.getTowns().stream().map(Town::getName).collect(Collectors.toCollection(ArrayList::new)); // Creates a snapshot of towns, new towns will be added when needed
Nations = dataSource.getNations().stream().map(Nation::getName).collect(Collectors.toCollection(ArrayList::new)); // Same here but with nations
TBMCChatAPI.RegisterChatChannel(
TownChat = new Channel("§3TC§f", Color.DarkAqua, "tc", s -> checkTownNationChat(s, false)));
TBMCChatAPI.registerChatChannel(
TBMCChatAPI.RegisterChatChannel(
NationChat = new Channel("§6NC§f", Color.Gold, "nc", s -> checkTownNationChat(s, true)));
TownyAnnouncer.setup(TownChat, NationChat);
}
@ -51,34 +65,39 @@ public class TownyComponent extends Component<PluginMain> {
TownyAnnouncer.setdown();
}
public Consumer<Player> handleSpiesInit(Channel channel, TextComponent.Builder json) {
if (channel.getIdentifier().equals(TownChat.getIdentifier()) || channel.getIdentifier().equals(NationChat.getIdentifier())) {
// TODO: Cannot prepend to json, so we need to run this ealier
//((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]"));
return p -> handleSpies(channel, p, json);
public Consumer<Player> handleSpiesInit(Channel channel, TellrawPart json, Function<TellrawPart, String> toJson,
CommandSender sender, String message) {
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]"));
String jsonstr = toJson.apply(json);
return p -> handleSpies(channel, p, jsonstr, sender, message);
}
return p -> {};
}
private void handleSpies(Channel channel, Player p, TextComponent.Builder jsonstr) {
if (channel.getIdentifier().equals(TownChat.getIdentifier()) || channel.getIdentifier().equals(NationChat.getIdentifier())) {
val res = dataSource.getResident(p.getName());
if (res == null) {
return;
private void handleSpies(Channel channel, Player p, String jsonstr, CommandSender sender, String message) {
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
try {
if (dataSource.getResident(p.getName()).hasMode("spy"))
if (!VanillaUtils.tellRaw(p, jsonstr))
ChatUtils.sendChatMessage(channel, sender, message, p);
} catch (NotRegisteredException ignored) {
}
if (res.hasMode("spy"))
p.sendMessage(jsonstr.build());
}
}
/**
* Return the error message for the message sender if they can't send it and the score
*/
private static Channel.RecipientTestResult checkTownNationChat(ChromaGamerBase user, boolean nationchat) {
if (!(user instanceof TBMCPlayerBase))
private static Channel.RecipientTestResult checkTownNationChat(CommandSender sender, boolean nationchat) {
if (!(sender instanceof Player))
return new Channel.RecipientTestResult("§cYou are not a player!");
val sender = ((TBMCPlayerBase) user).getOfflinePlayer();
Resident resident = dataSource.getResident(sender.getName());
Resident resident;
try {
resident = dataSource.getResident(sender.getName());
} catch (NotRegisteredException e) {
resident = null;
}
Channel.RecipientTestResult result = checkTownNationChatInternal(nationchat, resident);
if (result.errormessage != null && resident != null && resident.getModes().contains("spy")) // Only use spy if they wouldn't see it
result = new Channel.RecipientTestResult(1000, "allspies"); // There won't be more than a thousand towns/nations probably

View file

@ -7,7 +7,6 @@ import buttondevteam.chat.commands.ucmds.HistoryCommand;
import buttondevteam.chat.components.flair.FlairComponent;
import buttondevteam.chat.components.flair.FlairStates;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -54,7 +53,7 @@ public class PlayerJoinLeaveListener implements Listener {
PlayerListener.nicknames.forcePut(nwithoutformatting.toLowerCase(), p.getUniqueId());
if (PluginMain.Instance.storeChatHistory.get())
HistoryCommand.showHistory(ChromaGamerBase.getFromSender(e.getPlayer()), null);
HistoryCommand.showHistory(e.getPlayer(), null);
}
@EventHandler

View file

@ -10,7 +10,6 @@ import buttondevteam.chat.components.towncolors.TownColorComponent;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
import buttondevteam.lib.player.TBMCPlayerGetInfoEvent;
import com.google.common.collect.BiMap;
@ -57,7 +56,7 @@ public class PlayerListener implements Listener {
ChatPlayer cp = e.getPlayer().getAs(ChatPlayer.class);
if (cp == null)
return;
e.addInfo("Minecraft name: " + cp.getPlayerName());
e.addInfo("Minecraft name: " + cp.PlayerName.get());
if (cp.UserName.get() != null && cp.UserName.get().length() > 0)
e.addInfo("Reddit name: " + cp.UserName.get());
if (ComponentManager.isEnabled(FlairComponent.class)) {
@ -75,15 +74,15 @@ public class PlayerListener implements Listener {
try {
if (e.isCancelled())
return;
HistoryCommand.addChatMessage(e.getChatMessage(), e.getChannel());
HistoryCommand.addChatMessage(e.getCm(), e.getChannel());
e.setCancelled(FormatterComponent.handleChat(e));
} catch (NoClassDefFoundError | Exception ex) { // Weird things can happen
if (lastError < System.nanoTime() - 1000L * 1000L * 1000L * 60 * 60 //60 mins
&& Bukkit.getOnlinePlayers().size() > 0) { //If there are no players on, display to the first person
lastError = System.nanoTime(); //I put the whole thing in the if to protect against race conditions
for (Player p : Bukkit.getOnlinePlayers())
if (e.shouldSendTo(ChromaGamerBase.getFromSender(p)))
p.sendMessage("[" + e.getChannel().displayName.get() + "] §cSome features in the message below might be unavailable due to an error.");
if (e.shouldSendTo(p))
p.sendMessage("[" + e.getChannel().DisplayName.get() + "] §cSome features in the message below might be unavailable due to an error.");
}
ChatUtils.sendChatMessage(e);
TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex, PluginMain.Instance);

View file

@ -1,126 +1,125 @@
package buttondevteam.chat.components.formatter;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.ChatUtils;
import buttondevteam.chat.ObjectTestRunner;
import buttondevteam.chat.ObjectTestRunner.Objects;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import buttondevteam.chat.components.formatter.formatting.ChatFormatter;
import buttondevteam.chat.components.formatter.formatting.FormatSettings;
import buttondevteam.chat.components.formatter.formatting.MatchProviderBase;
import buttondevteam.core.MainPlugin;
import buttondevteam.chat.components.formatter.formatting.*;
import buttondevteam.chat.components.formatter.formatting.TellrawEvent.ClickAction;
import buttondevteam.chat.components.formatter.formatting.TellrawEvent.HoverAction;
import buttondevteam.core.TestPrepare;
import buttondevteam.core.component.channel.Channel;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.test.TestPermissions;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.command.CommandSender;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import static be.seeseemelk.mockbukkit.MockBukkit.load;
import static be.seeseemelk.mockbukkit.MockBukkit.mock;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.event.ClickEvent.Action.OPEN_URL;
import static net.kyori.adventure.text.event.ClickEvent.clickEvent;
import static net.kyori.adventure.text.event.HoverEvent.Action.SHOW_TEXT;
import static net.kyori.adventure.text.event.HoverEvent.hoverEvent;
import static net.kyori.adventure.text.format.NamedTextColor.*;
import static net.kyori.adventure.text.format.TextDecoration.*;
@RunWith(ObjectTestRunner.class)
public class ChatFormatIT {
@Objects
public static List<Object> data() {
mock();
load(MainPlugin.class, true);
var sender = ChromaGamerBase.getUser(UUID.randomUUID().toString(), ChatPlayer.class);
TestPrepare.PrepareServer();
final CommandSender sender = Mockito.mock(CommandSender.class);
DebugCommand.DebugMode = true;
PluginMain.permission = new TestPermissions();
PluginMain.permission = Mockito.mock(Permission.class);
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class, TBMCPlayer::new);
List<Object> list = new ArrayList<>();
list.add(new ChatFormatIT(sender, "*test*", text("test").decorate(ITALIC).color(WHITE)));
list.add(new ChatFormatIT(sender, "**test**", text("test").decorate(BOLD).color(WHITE)));
list.add(new ChatFormatIT(sender, "***test***", text("test").decorate(BOLD, ITALIC).color(WHITE)));
list.add(new ChatFormatIT(sender, "***__test__***", text("test").decorate(BOLD, ITALIC, UNDERLINED).color(WHITE)));
list.add(new ChatFormatIT(sender, "***__~~test~~__***", text("test").decorate(BOLD, ITALIC, UNDERLINED, STRIKETHROUGH).color(WHITE)));
list.add(new ChatFormatIT(sender, "¯\\\\\\_(ツ)\\_/¯", text("¯\\_(ツ)_/¯").color(WHITE)));
list.add(new ChatFormatIT(sender, "*test*", new TellrawPart("test").setItalic(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "**test**", new TellrawPart("test").setBold(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "***test***",
new TellrawPart("test").setBold(true).setItalic(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "***__test__***",
new TellrawPart("test").setBold(true).setItalic(true).setUnderlined(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "***__~~test~~__***", new TellrawPart("test").setBold(true).setItalic(true)
.setUnderlined(true).setStrikethrough(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "¯\\\\\\_(ツ)\\_/¯", new TellrawPart("¯\\_(ツ)_/¯").setColor(Color.White)));
list.add(new ChatFormatIT(sender, "https://google.hu/",
text("https://google.hu/").color(WHITE).decorate(UNDERLINED)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(BLUE)))
.clickEvent(clickEvent(OPEN_URL, "https://google.hu/"))));
list.add(new ChatFormatIT(sender, "*test", text("*test").color(WHITE)));
list.add(new ChatFormatIT(sender, "**test*", text("**test*").color(WHITE)));
list.add(new ChatFormatIT(sender, "***test", text("***test").color(WHITE)));
list.add(new ChatFormatIT(sender, "Koiiev", text("§bKoiiev§r").color(AQUA)));
list.add(new ChatFormatIT(sender, "norbipeti", text("§bNorbiPeti§r").color(AQUA)));
list.add(new ChatFormatIT(sender, "Arsen_Derby_FTW", text("§bArsen_Derby_FTW§r").color(AQUA)));
list.add(new ChatFormatIT(sender, "carrot_lynx", text("§bcarrot_lynx§r").color(AQUA)));
list.add(new ChatFormatIT(sender, "*carrot_lynx*", text("§bcarrot_lynx§r").decorate(ITALIC).color(AQUA)));
list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/", text("https://norbipeti.github.io/")
.color(WHITE).decorate(UNDERLINED)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(BLUE)))
.clickEvent(clickEvent(OPEN_URL, "https://norbipeti.github.io/"))));
list.add(new ChatFormatIT(sender, "*https://norbipeti.github.io/ heh*", text("https://norbipeti.github.io/").decorate(ITALIC).decorate(UNDERLINED)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(BLUE)))
.clickEvent(clickEvent(OPEN_URL, "https://norbipeti.github.io/")).color(WHITE), text(" heh").decorate(ITALIC).color(WHITE)));
list.add(new ChatFormatIT(sender, "*test _test_ test*", text("test test test").decorate(ITALIC).color(WHITE)));
list.add(new ChatFormatIT(sender, "*test __test__ test*", text("test ").decorate(ITALIC).color(WHITE),
text("test").decorate(ITALIC).decorate(UNDERLINED).color(WHITE), text(" test").decorate(ITALIC).color(WHITE)));
list.add(new ChatFormatIT(sender, "**test __test__ test**", text("test ").decorate(BOLD).color(WHITE),
text("test").decorate(BOLD).decorate(UNDERLINED).color(WHITE), text(" test").decorate(BOLD).color(WHITE)));
list.add(new ChatFormatIT(sender, "**test _test_ test**", text("test ").decorate(BOLD).color(WHITE),
text("test").decorate(ITALIC).decorate(BOLD).color(WHITE), text(" test").decorate(BOLD).color(WHITE)));
list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/test?test&test#test", text("https://norbipeti.github.io/test?test&test#test")
.color(WHITE).decorate(UNDERLINED)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(BLUE)))
.clickEvent(clickEvent(OPEN_URL, "https://norbipeti.github.io/test?test&test#test"))));
list.add(new ChatFormatIT(sender, "[hmm](https://norbipeti.github.io/test)", text("hmm")
.color(WHITE).decorate(UNDERLINED)
.hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(BLUE)))
.clickEvent(clickEvent(OPEN_URL, "https://norbipeti.github.io/test"))));
var space = text(" ").color(WHITE);
list.add(new ChatFormatIT(sender, "A rainbow text for testing. O", text("A").color(RED),
space, text("rainbow").color(GOLD), space, text("text").color(YELLOW),
space, text("for").color(GREEN), space, text("testing.").color(BLUE),
space, text("O").color(DARK_PURPLE)).setRainbowMode());
list.add(new ChatFormatIT(sender, "***test*** test", text("test").color(WHITE)
.decorate(ITALIC).decorate(BOLD), text(" test").color(WHITE)));
list.add(new ChatFormatIT(sender, ">test message\nheh", text(">test message\nheh").color(GREEN)));
list.add(new ChatFormatIT(sender, "[here's a link]()", text("[here's a link]()").color(WHITE)));
list.add(new ChatFormatIT(sender, "[](fakelink)", text("[](fakelink)").color(WHITE)));
list.add(new ChatFormatIT(sender, "||this is a spoiler||", text("this is a spoiler").color(WHITE)
.decorate(OBFUSCATED).hoverEvent(hoverEvent(SHOW_TEXT, text("this is a spoiler")))));
Function<String, TextComponent> whiteBoldItalic = text -> text(text).color(WHITE).decorate(BOLD).decorate(ITALIC);
new TellrawPart("https://google.hu/").setColor(Color.White).setUnderlined(true)
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
new TellrawPart("Click to open").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://google.hu/"))));
list.add(new ChatFormatIT(sender, "*test", new TellrawPart("*test").setColor(Color.White)));
list.add(new ChatFormatIT(sender, "**test*", new TellrawPart("**test*").setColor(Color.White)));
list.add(new ChatFormatIT(sender, "***test", new TellrawPart("***test").setColor(Color.White)));
list.add(new ChatFormatIT(sender, "Koiiev", new TellrawPart("§bKoiiev§r").setColor(Color.Aqua)));
list.add(new ChatFormatIT(sender, "norbipeti", new TellrawPart("§bNorbiPeti§r").setColor(Color.Aqua)));
list.add(new ChatFormatIT(sender, "Arsen_Derby_FTW", new TellrawPart("§bArsen_Derby_FTW§r").setColor(Color.Aqua)));
list.add(new ChatFormatIT(sender, "carrot_lynx", new TellrawPart("§bcarrot_lynx§r").setColor(Color.Aqua)));
list.add(new ChatFormatIT(sender, "*carrot_lynx*", new TellrawPart("§bcarrot_lynx§r").setItalic(true).setColor(Color.Aqua)));
list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/", new TellrawPart("https://norbipeti.github.io/")
.setColor(Color.White).setUnderlined(true)
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
new TellrawPart("Click to open").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/"))));
list.add(new ChatFormatIT(sender, "*https://norbipeti.github.io/ heh*", new TellrawPart("https://norbipeti.github.io/").setItalic(true).setUnderlined(true)
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
new TellrawPart("Click to open").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")).setColor(Color.White), new TellrawPart(" heh").setItalic(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "*test _test_ test*", new TellrawPart("test test test").setItalic(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "*test __test__ test*", new TellrawPart("test ").setItalic(true).setColor(Color.White),
new TellrawPart("test").setItalic(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setItalic(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "**test __test__ test**", new TellrawPart("test ").setBold(true).setColor(Color.White),
new TellrawPart("test").setBold(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setBold(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "**test _test_ test**", new TellrawPart("test ").setBold(true).setColor(Color.White),
new TellrawPart("test").setItalic(true).setBold(true).setColor(Color.White), new TellrawPart(" test").setBold(true).setColor(Color.White)));
list.add(new ChatFormatIT(sender, "https://norbipeti.github.io/test?test&test#test", new TellrawPart("https://norbipeti.github.io/test?test&test#test")
.setColor(Color.White).setUnderlined(true)
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
new TellrawPart("Click to open").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/test?test&test#test"))));
list.add(new ChatFormatIT(sender, "[hmm](https://norbipeti.github.io/test)", new TellrawPart("hmm")
.setColor(Color.White).setUnderlined(true)
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
new TellrawPart("Click to open").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/test"))));
TellrawPart space = new TellrawPart(" ").setColor(Color.White);
list.add(new ChatFormatIT(sender, "A rainbow text for testing. O", new TellrawPart("A").setColor(Color.Red),
space, new TellrawPart("rainbow").setColor(Color.Gold), space, new TellrawPart("text").setColor(Color.Yellow),
space, new TellrawPart("for").setColor(Color.Green), space, new TellrawPart("testing.").setColor(Color.Blue),
space, new TellrawPart("O").setColor(Color.DarkPurple)).setRainbowMode());
list.add(new ChatFormatIT(sender, "***test*** test", new TellrawPart("test").setColor(Color.White)
.setItalic(true).setBold(true), new TellrawPart(" test").setColor(Color.White)));
list.add(new ChatFormatIT(sender, ">test message\nheh", new TellrawPart(">test message\nheh").setColor(Color.Green)));
list.add(new ChatFormatIT(sender, "[here's a link]()", new TellrawPart("[here's a link]()").setColor(Color.White)));
list.add(new ChatFormatIT(sender, "[](fakelink)", new TellrawPart("[](fakelink)").setColor(Color.White)));
list.add(new ChatFormatIT(sender, "||this is a spoiler||", new TellrawPart("this is a spoiler").setColor(Color.White)
.setObfuscated(true).setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, "this is a spoiler"))));
Function<String, TellrawPart> whiteBoldItalic = text -> new TellrawPart(text).setColor(Color.White).setBold(true).setItalic(true);
list.add(new ChatFormatIT(sender, "***some complicated ||test message|| with [links](https://chromagaming.figytuna.com) and other __greatness__ by NorbiPeti***",
whiteBoldItalic.apply("some complicated "),
whiteBoldItalic.apply("test message").decorate(OBFUSCATED).hoverEvent(hoverEvent(SHOW_TEXT, text("test message"))),
whiteBoldItalic.apply("test message").setObfuscated(true).setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, "test message")),
whiteBoldItalic.apply(" with "),
whiteBoldItalic.apply("links").clickEvent(clickEvent(OPEN_URL, "https://chromagaming.figytuna.com"))
.decorate(UNDERLINED).hoverEvent(hoverEvent(SHOW_TEXT, text("Click to open").color(BLUE))),
whiteBoldItalic.apply("links").setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://chromagaming.figytuna.com")).setUnderlined(true)
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT, new TellrawPart("Click to open").setColor(Color.Blue))),
whiteBoldItalic.apply(" and other "),
whiteBoldItalic.apply("greatness").decorate(UNDERLINED),
whiteBoldItalic.apply("greatness").setUnderlined(true),
whiteBoldItalic.apply(" by "),
whiteBoldItalic.apply("§bNorbiPeti§r").color(AQUA))); //§b: flair color
list.add(new ChatFormatIT(sender, "hey @console", text("hey ").color(WHITE),
text("@console").color(AQUA)));
whiteBoldItalic.apply("§bNorbiPeti§r").setColor(Color.Aqua))); //§b: flair color
list.add(new ChatFormatIT(sender, "hey @console", new TellrawPart("hey ").setColor(Color.White),
new TellrawPart("@console").setColor(Color.Aqua)));
return list;
}
private final ChromaGamerBase sender;
private final CommandSender sender;
private final String message;
private final Component[] extras;
private final TellrawPart[] extras;
private boolean rainbowMode;
public ChatFormatIT(ChromaGamerBase sender, String message, Component... expectedExtras) {
public ChatFormatIT(CommandSender sender, String message, TellrawPart... expectedExtras) {
this.sender = sender;
this.message = message;
this.extras = expectedExtras;
@ -135,14 +134,14 @@ public class ChatFormatIT {
public void testMessage() {
System.out.println("Testing: " + message);
ArrayList<MatchProviderBase> cfs = ChatProcessing.addFormatters(p -> true, null);
final String chid = ChatProcessing.getChannelID(Channel.globalChat, ChatUtils.MCORIGIN);
final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN);
if (rainbowMode)
ChatProcessing.createRPC(WHITE, cfs);
final TextComponent.Builder tp = ChatProcessing.createEmptyMessageLine(sender, message, null, chid, ChatUtils.MCORIGIN);
ChatFormatter.Combine(cfs, message, tp, null, FormatSettings.builder().color(WHITE).build());
final TextComponent.Builder expectedtp = ChatProcessing.createEmptyMessageLine(sender, message, null, chid, ChatUtils.MCORIGIN);
for (Component extra : extras)
expectedtp.append(extra);
Assert.assertEquals(expectedtp.build(), tp.build());
ChatProcessing.createRPC(Color.White, cfs);
final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
ChatFormatter.Combine(cfs, message, tp, null, FormatSettings.builder().color(Color.White).build());
final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
for (TellrawPart extra : extras)
expectedtp.addExtra(extra);
Assert.assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp));
}
}