Compare commits

..

No commits in common. "master" and "v1.0-pre5" have entirely different histories.

47 changed files with 944 additions and 793 deletions

View file

@ -7,15 +7,17 @@ before_install: | # Wget BuildTools and run if cached folder not found
# grep so that download counts don't appear in log files
java -jar BuildTools.jar --rev 1.12.2 | grep -vE "[^/ ]*/[^/ ]*\s*KB\s*$" | grep -v "^\s*$"
fi
cp ci/settings.xml $HOME/.m2/
language: java
jdk:
- oraclejdk11
- oraclejdk8
sudo: true
dist: trusty # Needed for Java 8, although we might not need Java 8
deploy:
- provider: releases
api_key:
secure: "F5YiEuD6LyRENUDMCslcSl0O0dg4IDk+nNeb4X2VLYlmb8dW9beMuIgjH8efTMeaQ3D/ntIkN0Dtf2GKvpOduhwkSbAgw4WM028X60SY9f2hmpEO3LmM4T1tKoDlI1T3BmhYP4KeTKBYn+etV1mSPbT07vUybCm/vGzvr96yMZGNFEoKsWLaEu7dZfBFULj4tXOwrLh/KO6BsdAHvZcGKWNVupPq3YoUVT0dpGcUudf5cpn+aaqMwyd709zgMbyCuqf+c5Udps43q4EKvr9z7TWxFUkGTPVVAcUVygJsi2ytuyA8TLMPq/KhYe9htnkNUnizbqv/j49xww0gVaD7OJXENJ4hAUTV4sdn1DXG45JXW+dir3V7YzbRYn3M+eCuKB2O77SXRZBkxcGtTMtCmghP9/tcRAQlXDXnxu7oAnlUVp17g/+aFApvlzZEZVx2N+fkyEe7JrUFlRCixtHyrmTLWhyV0Px9p0FHJpvSSCL0S0UKVAT/sNHYHhD5gouK7owEomEbG58XCsRDH6Et7RuDksB98ekK8brZp6S7dNIS2CVuVx1vIkXC8PzUGcpJQoztvEYUE20Axahh5s8AkE9n/O9jzs9ajcfYaHhWzYeUZzHdHllOYF9l6VoCUitTk4Sl8eJifSq3GzI+T6wGMBepZHLpe230MvBIrqGZ+Vg="
file: 'target/Chroma-Chat.jar'
file: 'Chroma-Core/target/Chroma-Core.jar'
on:
tags: true
skip_cleanup: true

36
ci/settings.xml Normal file
View file

@ -0,0 +1,36 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<activeProfiles>
<activeProfile>github</activeProfile>
</activeProfiles>
<profiles>
<profile>
<id>github</id>
<repositories>
<!-- <repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository> -->
<repository>
<id>github</id>
<name>GitHub Towny Apache Maven Packages</name>
<url>https://maven.pkg.github.com/TownyAdvanced/Towny</url>
</repository>
</repositories>
</profile>
</profiles>
<servers>
<server>
<id>github</id>
<username>NorbiPeti</username>
<password>${env.GHTOKEN}</password>
</server>
</servers>
</settings>

193
pom.xml
View file

@ -6,12 +6,18 @@
<artifactId>CorePOM</artifactId>
<version>master-SNAPSHOT</version>
</parent>
<version>v${noprefix.version}-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
<name>Chroma-Chat Plugin</name>
<description>Chroma-Chat Plugin</description>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
@ -25,6 +31,26 @@
</resources>
<finalName>Chroma-Chat</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>net.sourceforge.htmlcleaner:htmlcleaner</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
@ -65,6 +91,64 @@
<useSystemClassLoader>false
</useSystemClassLoader> <!-- https://stackoverflow.com/a/53012553/2703239 -->
</configuration>
</plugin>
<!-- <plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.5</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
*NOTE*: The default phase of revision is initialize, but in case you want to change it, you can do so by adding the phase here
<phase>initialize</phase>
<configuration>
<injectAllReactorProjects>true</injectAllReactorProjects>
</configuration>
</execution>
<execution>
<id>validate-the-git-infos</id>
<goals>
<goal>validateRevision</goal>
</goals>
*NOTE*: The default phase of validateRevision is verify, but in case you want to change it, you can do so by adding the phase here
<phase>package</phase>
<configuration>
<validationProperties>
- <validationProperty>
<name>validating git dirty</name>
<value>${git.branch}</value>
<shouldMatchTo>dev</shouldMatchTo>
</validationProperty> -
</validationProperties>
</configuration>
</execution>
</executions>
<configuration>
<injectAllReactorProjects>true</injectAllReactorProjects>
<verbose>true</verbose>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
</configuration>
</plugin> -->
<!-- <plugin> <groupId>org.basepom.maven</groupId> <artifactId>duplicate-finder-maven-plugin</artifactId>
<version>1.2.1</version> <executions> <execution> <goals> <goal>check</goal>
</goals> </execution> </executions> </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>
@ -80,7 +164,7 @@
</repository>
<repository>
<id>ess-repo</id>
<url>https://repo.essentialsx.net/releases/</url>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
<!-- <repository>
<id>Minigames</id>
@ -94,105 +178,101 @@
</repository> -->
<repository>
<id>projectlombok.org</id>
<url>https://projectlombok.org/mavenrepo</url>
</repository>
<repository>
<id>Dynmap</id>
<url>https://repo.mikeprimm.com</url>
</repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
<url>http://projectlombok.org/mavenrepo</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>
<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>v2.0.0-SNAPSHOT</version>
<version>${branch}-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sourceforge.htmlcleaner/htmlcleaner -->
<dependency>
<groupId>net.sourceforge.htmlcleaner</groupId>
<artifactId>htmlcleaner</artifactId>
<version>2.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<dependency>
<groupId>net.essentialsx</groupId>
<groupId>net.ess3</groupId>
<artifactId>EssentialsX</artifactId>
<version>2.19.2</version>
<version>2.17.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.TownyAdvanced</groupId>
<groupId>com.palmergames.bukkit.towny</groupId>
<artifactId>Towny</artifactId>
<!-- <version>8d3b6b6</version> ButtonCore repo -->
<version>0.98.6.0</version>
<version>0.95.2.0</version>
<scope>provided</scope>
</dependency>
<!-- <dependency> <groupId>au.com.mineauz</groupId> <artifactId>Minigames</artifactId>
<version>1.8.0</version> </dependency> -->
<dependency>
<groupId>com.github.MilkBowl</groupId>
<groupId>com.github.milkbowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<version>master-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<version>1.18.10</version>
<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>
<version>1.16.4-R0.1-SNAPSHOT</version>
<version>1.14.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency> -->
<dependency>
<groupId>com.github.TownyAdvanced</groupId>
<groupId>com.github.webbukkit</groupId>
<artifactId>Dynmap-Towny</artifactId>
<version>0.89</version>
<version>master-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>us.dynmap</groupId>
<artifactId>dynmap-api</artifactId>
<version>3.2-beta-1</version>
<groupId>com.github.webbukkit</groupId>
<artifactId>Dynmap</artifactId>
<version>v2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Included in vanilla minecraft's JAR -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.0</version>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
<!-- TestPrepare also needs it (ChromaCore) so the versions should match -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<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>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -205,6 +285,23 @@
<!-- github server corresponds to entry in ~/.m2/settings.xml -->
<github.global.server>githubo</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<noprefix.version>1.0.0</noprefix.version>
<branch>
master
</branch> <!-- Should be master if building ButtonCore locally - the CI will overwrite it (see below) -->
</properties>
<profiles>
<profile>
<id>ci</id>
<activation>
<property>
<name>env.TRAVIS_BRANCH</name>
</property>
</activation>
<properties>
<!-- Override only if necessary -->
<branch>${env.TRAVIS_BRANCH}</branch>
</properties>
</profile>
</profiles>
</project>

View file

@ -1,34 +1,50 @@
package buttondevteam.chat;
import buttondevteam.chat.components.flair.FlairStates;
import buttondevteam.lib.architecture.config.IConfigData;
import buttondevteam.lib.architecture.config.IListConfigData;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.player.EnumPlayerData;
import buttondevteam.lib.player.PlayerClass;
import buttondevteam.lib.player.PlayerData;
import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
@PlayerClass(pluginname = "Chroma-Chat")
@PlayerClass(pluginname = "Button1Chat")
public class ChatPlayer extends TBMCPlayerBase {
public final IConfigData<String> UserName = getConfig().getData("UserName", "");
public PlayerData<String> UserName() {
return data(null);
}
public final IListConfigData<String> UserNames = getConfig().getListData("UserNames", Collections.emptyList());
public List<String> UserNames() {
return data(new ArrayList<String>()).get();
}
public final IConfigData<Integer> FlairTime = getConfig().getData("FlairTime", FlairTimeNone);
public PlayerData<Integer> FlairTime() {
return data(FlairTimeNone);
}
public final IConfigData<FlairStates> FlairState = getConfig().getData("FlairState", FlairStates.NoComment,
fs -> FlairStates.valueOf((String) fs), FlairStates::toString);
public EnumPlayerData<FlairStates> FlairState() {
return dataEnum(FlairStates.class, FlairStates.NoComment);
}
public final IConfigData<Integer> FCount = getConfig().getData("FCount", 0);
public PlayerData<Integer> FCount() {
return data(0);
}
public final IConfigData<Integer> FDeaths = getConfig().getData("FDeaths", 0);
public PlayerData<Integer> FDeaths() {
return data(0);
}
public final IConfigData<Boolean> FlairCheater = getConfig().getData("FlairCheater", false);
public PlayerData<Boolean> FlairCheater() {
return data(false);
}
public final IListConfigData<Integer> NameColorLocations = getConfig().getListData("NameColorLocations", Collections.emptyList()); // No byte[], no TIntArrayList
public PlayerData<ArrayList<Integer>> NameColorLocations() { // No byte[], no TIntArrayList
return data(null);
}
public boolean Working;
// public int Tables = 10;
@ -48,7 +64,7 @@ public class ChatPlayer extends TBMCPlayerBase {
* @return The flair
*/
public String GetFormattedFlair(boolean noformats) {
int time = FlairTime.get();
int time = FlairTime().get();
if (time == FlairTimeCantPress)
return noformats ? "(can't press)" : "§r(--s)§r";
if (time == FlairTimeNonPresser)
@ -68,13 +84,13 @@ public class ChatPlayer extends TBMCPlayerBase {
}
public void SetFlair(int time) {
FlairTime.set(time);
FlairTime().set(time);
FlairUpdate();
}
public void SetFlair(int time, boolean cheater) {
FlairTime.set(time);
FlairCheater.set(cheater);
FlairTime().set(time);
FlairCheater().set(cheater);
FlairUpdate();
}
@ -82,15 +98,15 @@ 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()));
}
public short GetFlairColor() {
if (FlairCheater.get())
if (FlairCheater().get())
return 0x5;
final int flairTime = FlairTime.get();
final int flairTime = FlairTime().get();
if (flairTime == FlairTimeNonPresser)
return 0x7;
else if (flairTime == FlairTimeCantPress)
@ -111,6 +127,6 @@ public class ChatPlayer extends TBMCPlayerBase {
}
public double getF() {
return (double) FCount.get() / (double) FDeaths.get();
return (double) FCount().get() / (double) FDeaths().get();
}
}

View file

@ -1,13 +1,12 @@
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;
import java.util.Optional;
import java.util.function.Function;
public final class ChatUtils {
public static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized
@ -46,20 +45,15 @@ public final class ChatUtils {
* Sends a regular (non-Markdown) chat message. Used as a fallback if the chat processing fails.
*
* @param e The chat event
* @param modifier A function that alters the message to be displayed to the player
*/
public static void sendChatMessage(TBMCChatEvent e) {
var str = getMessageString(e.getChannel(), e.getUser(), e.getMessage());
public static void sendChatMessage(TBMCChatEvent e, Function<String, String> modifier) {
var str = "[" + e.getChannel().DisplayName().get() + "] <"
+ ChromaUtils.getDisplayName(e.getSender()) + "> " + e.getMessage();
str = modifier.apply(str);
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 void sendChatMessage(Channel channel, ChromaGamerBase sender, String message, CommandSender to) {
to.sendMessage(getMessageString(channel, sender, message));
}
}

View file

@ -21,16 +21,19 @@ 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;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.RegisteredServiceProvider;
public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15.
// A user, which flair isn't obtainable:
// https://www.reddit.com/r/thebutton/comments/31c32v/i_pressed_the_button_without_really_thinking/
public static PluginMain Instance;
public static ConsoleCommandSender Console;
@ -38,7 +41,9 @@ 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() {
return getIConfig().getData("storeChatHistory", true);
}
// Fired when plugin is first enabled
@Override
@ -53,10 +58,10 @@ 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);
if (!setupEconomy() || !setupPermissions())
TBMCCoreAPI.SendException("We're in trouble", new Exception("Failed to set up economy or permissions!"));
if (Bukkit.getPluginManager().isPluginEnabled("Towny"))
Component.registerComponent(this, new TownColorComponent());
@ -83,6 +88,7 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
}
public static Permission permission = null;
public static Economy economy = null;
private boolean setupPermissions() {
RegisteredServiceProvider<Permission> permissionProvider = getServer().getServicesManager()
@ -93,4 +99,14 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
return (permission != null);
}
private boolean setupEconomy() {
RegisteredServiceProvider<Economy> economyProvider = getServer().getServicesManager()
.getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
economy = economyProvider.getProvider();
}
return (economy != null);
}
}

View file

@ -2,14 +2,10 @@ 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;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
@ -17,12 +13,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;
@ -81,22 +79,9 @@ public class VanillaUtils {
if (notCraftPlayer(pcl)) return false;
val hm = pcl.getMethod("getHandle");
val handle = hm.invoke(p);
var nmsOrChat = handle.getClass().getPackage().getName();
if (!nmsOrChat.contains(".v1_"))
nmsOrChat = "net.minecraft.network.chat";
val chatcompcl = Class.forName(nmsOrChat + ".IChatBaseComponent");
//val chatcomarrcl = Class.forName("[L" + chatcompcl.getName() + ";");
val chatcomparr = Array.newInstance(chatcompcl, 1);
final Method sendmsg;
{
Method sendmsg1;
try {
sendmsg1 = handle.getClass().getMethod("sendMessage", UUID.class, chatcomparr.getClass());
} catch (NoSuchMethodException e) {
sendmsg1 = handle.getClass().getMethod("sendMessage", chatcomparr.getClass());
}
sendmsg = sendmsg1;
}
val nms = handle.getClass().getPackage().getName();
val chatcompcl = Class.forName(nms + ".IChatBaseComponent");
val sendmsg = handle.getClass().getMethod("sendMessage", chatcompcl);
/*val ccucl = Class.forName(nms + ".ChatComponentUtils");
val iclcl = Class.forName(nms + ".ICommandListener");
@ -112,11 +97,7 @@ public class VanillaUtils {
val hhandle = hm.invoke(pl);
val deserialized = am.invoke(null, jsonStr);
//val filtered = ffdm.invoke(null, hhandle, deserialized, hhandle);
Array.set(chatcomparr, 0, deserialized);
if (sendmsg.getParameterCount() == 2)
sendmsg.invoke(hhandle, null, chatcomparr); //
else
sendmsg.invoke(hhandle, chatcomparr);
sendmsg.invoke(hhandle, deserialized);
return true;
} catch (Exception e) {
e.printStackTrace();

View file

@ -10,6 +10,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* " + sender.getName() + " " + message, TBMCSystemChatEvent.BroadcastTarget.ALL);
}
}

View file

@ -10,10 +10,7 @@ import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.Random;
@CommandClass(modOnly = true, helpText = {
"Snap",
"Perfectly balanced as all things should be."
})
@CommandClass(modOnly = true)
public class SnapCommand extends ICommand2MC {
@Command2.Subcommand
public void def(CommandSender sender) {

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) {
if (!PluginMain.Instance.storeChatHistory.get()) {
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,21 +66,25 @@ 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;
}
@RequiredArgsConstructor
private static class HistoryEntry {
/**
* @param timestamp System.nanoTime()
* System.nanoTime()
*/
private record HistoryEntry(long timestamp, ChatMessage chatMessage, Channel channel) {
private final long timestamp;
private final ChatMessage chatMessage;
private final Channel channel;
}
public static void addChatMessage(ChatMessage chatMessage, Channel channel) {
if (!PluginMain.Instance.storeChatHistory.get()) return;
if (!PluginMain.Instance.storeChatHistory().get()) return;
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,6 +1,7 @@
package buttondevteam.chat.commands.ucmds;
import buttondevteam.chat.PluginMain;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
@ -18,12 +19,16 @@ public class InfoCommand extends UCommandBase {
@Command2.Subcommand
public boolean def(CommandSender sender, OfflinePlayer player) {
Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {
TBMCPlayer p = TBMCPlayerBase.getPlayer(player.getUniqueId(), TBMCPlayer.class);
try (TBMCPlayer p = TBMCPlayerBase.getPlayer(player.getUniqueId(), TBMCPlayer.class)) {
if (p == null) {
sender.sendMessage("§cThe specified player cannot be found");
return;
}
sender.sendMessage(p.getInfo(InfoTarget.MCCommand));
} catch (Exception e) {
TBMCCoreAPI.SendException("Error while getting player information!", e);
sender.sendMessage("§cError while getting player information!");
}
});
return true;
}

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 {
@ -27,7 +24,7 @@ public class AnnounceCommand extends UCommandBase {
})
public boolean add(CommandSender sender, @Command2.TextArg String text) {
String finalmessage = text.replace('&', '§');
component.announceMessages.get().add(finalmessage);
component.announceMessages().get().add(finalmessage);
sender.sendMessage("§bAnnouncement added.§r");
return true;
}
@ -41,9 +38,9 @@ public class AnnounceCommand extends UCommandBase {
String finalmessage1 = text.replace('&', '§');
if (index > 100)
return false;
while (component.announceMessages.get().size() <= index)
component.announceMessages.get().add("");
component.announceMessages.get().set(index, finalmessage1);
while (component.announceMessages().get().size() <= index)
component.announceMessages().get().add("");
component.announceMessages().get().set(index, finalmessage1);
sender.sendMessage("Announcement edited.");
return true;
}
@ -56,19 +53,21 @@ public class AnnounceCommand extends UCommandBase {
sender.sendMessage("§bList of announce messages:§r");
sender.sendMessage("§bFormat: [index] message§r");
int i = 0;
for (String message : component.announceMessages.get()) {
for (String message : component.announceMessages().get()) {
String msg = "[" + i++ + "] " + message;
//noinspection SuspiciousMethodCalls
if (!ComponentManager.isEnabled(FormatterComponent.class) || !Bukkit.getOnlinePlayers().contains(sender)) {
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");
+ component.announceTime().get() / 60 / 1000 + " minute(s)§r");
return true;
}
@ -77,7 +76,7 @@ public class AnnounceCommand extends UCommandBase {
"This command removes an announcement"
})
public boolean remove(CommandSender sender, int index) {
val msgs = component.announceMessages.get();
val msgs = component.announceMessages().get();
if (index < 0 || index > msgs.size()) return false;
msgs.remove(index);
sender.sendMessage("Announcement removed.");
@ -89,7 +88,7 @@ public class AnnounceCommand extends UCommandBase {
"This command sets the time between the announcements"
})
public boolean settime(CommandSender sender, int minutes) {
component.announceTime.set(minutes * 60 * 1000);
component.announceTime().set(minutes * 60 * 1000);
sender.sendMessage("Time set between announce messages to " + minutes + " minutes");
return true;
}

View file

@ -4,28 +4,28 @@ import buttondevteam.chat.PluginMain;
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.
*/
@ComponentMetadata(enabledByDefault = false)
public class AnnouncerComponent extends Component<PluginMain> implements Runnable {
/**
* The messages to display to players.
*/
public IListConfigData<String> announceMessages = getConfig().getListData("announceMessages", Collections.emptyList());
public ListConfigData<String> announceMessages() {
return 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() {
return getConfig().getData("announceTime", 15 * 60 * 1000);
}
private TBMCSystemChatEvent.BroadcastTarget target;
@ -35,15 +35,15 @@ public class AnnouncerComponent extends Component<PluginMain> implements Runnabl
public void run() {
while (isEnabled()) {
try {
Thread.sleep(announceTime.get());
Thread.sleep(announceTime().get());
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
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);
if (announceMessages().get().size() > AnnounceMessageIndex) {
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, announceMessages().get().get(AnnounceMessageIndex), target);
AnnounceMessageIndex++;
if (AnnounceMessageIndex == announceMessages.get().size())
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
@ -66,7 +67,7 @@ public class AppendTextComponent extends Component<PluginMain> {
});
appendedText(conf).set("( ͡° ͜ʖ ͡°)");
});
map.put("waitwhat", conf -> {
map.put("ww", conf -> {
helpText(conf).set(new String[]{
"Wait what", //
"Wait what" //
@ -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,24 +2,21 @@ 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 buttondevteam.lib.player.TBMCPlayerJoinEvent;
import lombok.val;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.GameMode;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
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.
*/
@ -37,20 +34,21 @@ public class ChatOnlyComponent extends Component<PluginMain> implements Listener
}
@EventHandler
public void playerJoin(PlayerJoinEvent event) {
public void playerJoin(TBMCPlayerJoinEvent event) {
val p = event.getPlayer();
val cp = TBMCPlayer.getPlayer(p.getUniqueId(), ChatPlayer.class);
val cp = event.GetPlayer().asPluginPlayer(ChatPlayer.class);
if (cp.ChatOnly || p.getGameMode().equals(GameMode.SPECTATOR)) {
cp.ChatOnly = false;
p.setGameMode(GameMode.SURVIVAL);
}
}
public static void tellrawCreate(ChatPlayer mp, TextComponent.Builder json) {
if (!ComponentManager.isEnabled(ChatOnlyComponent.class))
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

@ -24,21 +24,21 @@ public class AcceptCommand extends UCommandBase {
@Command2.Subcommand
public boolean def(Player player, @Command2.OptionalArg String username) {
ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class);
if (username == null && p.UserNames.get().size() > 1) {
if (username == null && p.UserNames().size() > 1) {
player.sendMessage("§9Multiple users commented your name. §bPlease pick one using /u accept <username>");
StringBuilder sb = new StringBuilder();
sb.append("§6Usernames:");
for (String name : p.UserNames.get())
for (String name : p.UserNames())
sb.append(" ").append(name);
player.sendMessage(sb.toString());
return true;
}
if (p.FlairState.get().equals(FlairStates.NoComment) || p.UserNames.get().size() == 0) {
if (p.FlairState().get().equals(FlairStates.NoComment) || p.UserNames().size() == 0) {
player.sendMessage("§cError: You need to write your username to the reddit thread§r");
player.sendMessage(component.flairThreadURL.get());
player.sendMessage(component.flairThreadURL().get());
return true;
}
if (username != null && !p.UserNames.get().contains(username)) {
if (username != null && !p.UserNames().contains(username)) {
player.sendMessage("§cError: Unknown name: " + username + "§r");
return true;
}
@ -47,14 +47,14 @@ public class AcceptCommand extends UCommandBase {
return true;
}
if ((username != null ? username : p.UserNames.get().get(0)).equals(p.UserName.get())) {
if ((username != null ? username : p.UserNames().get(0)).equals(p.UserName().get())) {
player.sendMessage("§cYou already have this user's flair.§r");
return true;
}
if (username != null)
p.UserName.set(username);
p.UserName().set(username);
else
p.UserName.set(p.UserNames.get().get(0));
p.UserName().set(p.UserNames().get(0));
player.sendMessage("§bObtaining flair...");
p.Working = true;
@ -65,19 +65,22 @@ public class AcceptCommand extends UCommandBase {
try {
component.DownloadFlair(mp);
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while downloading flair for " + player.getCustomName() + "!", e, component);
player.sendMessage("Sorry, but an error occured while trying to get your flair. Please contact a mod.");
TBMCCoreAPI.SendException(
"An error occured while downloading flair for " + player.getCustomName() + "!", e);
player.sendMessage(
"Sorry, but an error occured while trying to get your flair. Please contact a mod.");
mp.Working = false;
return;
}
if (mp.FlairState.get().equals(FlairStates.Commented)) {
player.sendMessage("Sorry, but your flair isn't recorded. Please ask an admin to set it for you. Also, prepare a comment on /r/thebutton, if possible.");
if (mp.FlairState().get().equals(FlairStates.Commented)) {
player.sendMessage(
"Sorry, but your flair isn't recorded. Please ask an admin to set it for you. Also, prepare a comment on /r/thebutton, if possible.");
mp.Working = false;
return;
}
String flair = mp.GetFormattedFlair();
mp.FlairState.set(FlairStates.Accepted);
mp.FlairState().set(FlairStates.Accepted);
FlairComponent.ConfirmUserMessage(mp);
player.sendMessage("§bYour flair has been set:§r " + flair);
mp.Working = false;

View file

@ -5,18 +5,23 @@ 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;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Set;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* This component checks a specific Reddit thread every 10 seconds for comments such as "IGN: NorbiPeti" to link Reddit accounts and to determine their /r/thebutton flair.
@ -27,7 +32,9 @@ 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() {
return getConfig().getData("flairThreadURL", "");
}
/**
* <p>
@ -37,7 +44,7 @@ public class FlairComponent extends Component<PluginMain> {
* It's used because normally it has to load all associated player files every time to read the flair state
* </p>
*/
private final Set<String> PlayersWithFlairs = new HashSet<>();
private Set<String> PlayersWithFlairs = new HashSet<>();
@Override
protected void enable() {
@ -54,9 +61,9 @@ public class FlairComponent extends Component<PluginMain> {
private void FlairGetterThreadMethod() {
int errorcount = 0;
while (isEnabled() && flairThreadURL.get().length() > 0) {
while (isEnabled() && flairThreadURL().get().length() > 0) {
try {
String body = TBMCCoreAPI.DownloadString(flairThreadURL.get() + ".json?limit=1000");
String body = TBMCCoreAPI.DownloadString(flairThreadURL().get() + ".json?limit=1000");
JsonArray json = new JsonParser().parse(body).getAsJsonArray().get(1).getAsJsonObject().get("data")
.getAsJsonObject().get("children").getAsJsonArray();
for (Object obj : json) {
@ -76,27 +83,28 @@ public class FlairComponent extends Component<PluginMain> {
ign = ign.trim();
if (PlayersWithFlairs.contains(ign))
continue;
ChatPlayer mp = TBMCPlayerBase.getFromName(ign, ChatPlayer.class); // Loads player file
try (ChatPlayer mp = TBMCPlayerBase.getFromName(ign, ChatPlayer.class)) { // Loads player file
if (mp == null)
continue;
/*
* if (!JoinedBefore(mp, 2015, 6, 5)) continue;
*/
if (!mp.UserNames.get().contains(author))
mp.UserNames.get().add(author);
if (mp.FlairState.get().equals(FlairStates.NoComment)) {
mp.FlairState.set(FlairStates.Commented);
if (!mp.UserNames().contains(author))
mp.UserNames().add(author);
if (mp.FlairState().get().equals(FlairStates.NoComment)) {
mp.FlairState().set(FlairStates.Commented);
ConfirmUserMessage(mp);
}
PlayersWithFlairs.add(ign); // Don't redownload even if flair isn't accepted
}
}
} catch (Exception e) {
errorcount++;
if (errorcount >= 10) {
errorcount = 0;
if (!e.getMessage().contains("Server returned HTTP response code")
&& !(e instanceof UnknownHostException))
TBMCCoreAPI.SendException("Error while getting flairs from Reddit!", e, this);
TBMCCoreAPI.SendException("Error while getting flairs from Reddit!", e);
}
}
try {
@ -105,12 +113,11 @@ public class FlairComponent extends Component<PluginMain> {
Thread.currentThread().interrupt();
}
}
}
void DownloadFlair(ChatPlayer mp) throws IOException {
String[] flairdata = TBMCCoreAPI
.DownloadString("http://karmadecay.com/thebutton-data.php?users=" + mp.UserName.get())
.DownloadString("http://karmadecay.com/thebutton-data.php?users=" + mp.UserName().get())
.replace("\"", "").split(":");
String flair;
if (flairdata.length > 1)
@ -122,12 +129,12 @@ public class FlairComponent extends Component<PluginMain> {
flairclass = flairdata[2];
else
flairclass = "unknown";
SetFlair(mp, flair, flairclass, mp.UserName.get());
SetFlair(mp, flair, flairclass, mp.UserName().get());
}
private void SetFlair(ChatPlayer p, String text, String flairclass, String username) {
p.UserName.set(username);
p.FlairState.set(FlairStates.Recognised);
private static void SetFlair(ChatPlayer p, String text, String flairclass, String username) {
p.UserName().set(username);
p.FlairState().set(FlairStates.Recognised);
switch (flairclass) {
case "cheater":
p.SetFlair(Short.parseShort(text), true);
@ -143,9 +150,9 @@ public class FlairComponent extends Component<PluginMain> {
p.SetFlair(ChatPlayer.FlairTimeCantPress);
}
} catch (Exception e) {
p.FlairState.set(FlairStates.Commented); // Flair unknown
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);
}
return;
default:
@ -159,7 +166,7 @@ public class FlairComponent extends Component<PluginMain> {
}
private static boolean JoinedBefore(ChatPlayer mp, int year, int month, int day) throws Exception {
/*URL url = new URL("https://www.reddit.com/u/" + mp.UserName());
URL url = new URL("https://www.reddit.com/u/" + mp.UserName());
URLConnection con = url.openConnection();
con.setRequestProperty("User-Agent", "TheButtonAutoFlair");
InputStream in = con.getInputStream();
@ -173,14 +180,13 @@ public class FlairComponent extends Component<PluginMain> {
joindate = joindate.split("T")[0];
Date date = parserSDF.parse(joindate);
return date.before(new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("UTC")).setDate(year, month, day)
.build().getTime());*/
return true;
.build().getTime());
}
public static void ConfirmUserMessage(ChatPlayer mp) {
Player p = Bukkit.getPlayer(mp.getUniqueId());
if (mp.FlairState.get().equals(FlairStates.Commented) && p != null)
if (mp.UserNames.get().size() > 1)
Player p = Bukkit.getPlayer(mp.getUUID());
if (mp.FlairState().get().equals(FlairStates.Commented) && p != null)
if (mp.UserNames().size() > 1)
p.sendMessage(
"§9Multiple Reddit users commented your name. You can select with /u accept.§r §6Type /u accept or /u ignore§r");
else

View file

@ -15,18 +15,18 @@ public final class IgnoreCommand extends UCommandBase {
@Command2.Subcommand
public boolean def(Player player) {
ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class);
if (p.FlairState.get().equals(FlairStates.Accepted)) {
if (p.FlairState().get().equals(FlairStates.Accepted)) {
player.sendMessage("§cYou can only ignore the \"write your name in the thread\" message.");
return true;
}
if (p.FlairState.get().equals(FlairStates.Commented)) {
if (p.FlairState().get().equals(FlairStates.Commented)) {
player.sendMessage("Sorry, but your flair isn't recorded. Please ask a mod to set it for you.");
return true;
}
if (!p.FlairState.get().equals(FlairStates.Ignored)) {
p.FlairState.set(FlairStates.Ignored);
if (!p.FlairState().get().equals(FlairStates.Ignored)) {
p.FlairState().set(FlairStates.Ignored);
p.SetFlair(ChatPlayer.FlairTimeNone);
p.UserName.set("");
p.UserName().set("");
player.sendMessage("§bYou have ignored the message.§r");
} else
player.sendMessage("§cYou already ignored the message.§r");

View file

@ -41,15 +41,16 @@ public class SetFlairCommand extends AdminCommandBase {
}
ChatPlayer mp = TBMCPlayerBase.getPlayer(p.getUniqueId(), ChatPlayer.class);
mp.SetFlair(ft, cheater);
mp.FlairState.set(FlairStates.Accepted);
mp.FlairState().set(FlairStates.Accepted);
if (username == null)
mp.UserName.set("");
mp.UserName().set("");
else {
mp.UserName.set(username);
if (!mp.UserNames.get().contains(username))
mp.UserNames.get().add(username);
mp.UserName().set(username);
if (!mp.UserNames().contains(username))
mp.UserNames().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,23 +38,16 @@ 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;
private static final ArrayList<MatchProviderBase> commonFormatters = Lists.newArrayList(
private static ArrayList<MatchProviderBase> commonFormatters = Lists.newArrayList(
new RangeMatchProvider("bold", "**", FormatSettings.builder().bold(true).build()),
new RangeMatchProvider("italic", "*", FormatSettings.builder().italic(true).build()),
new RangeMatchProvider("underlined", "__", FormatSettings.builder().underlined(true).build()),
@ -67,8 +58,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,19 +68,19 @@ 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;
if (section.Matches.size() < 2 || (text = section.Matches.get(0)).length() == 0 || (link = section.Matches.get(1)).length() == 0)
return "[MISSING LINK]"; //Doesn't actually happen, because of the regex
return "";
builder.setOpenlink(link);
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());
@ -97,8 +88,12 @@ public class ChatProcessing {
var player = players.get(playerC);
playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class));
return "@someone (" + player.getDisplayName() + "§r)";
}).build(), true, "@someone"),
new RegexMatchProvider("greentext", GREENTEXT_PATTERN, FormatSettings.builder().color(GREEN).build()));
}).build(), true, "@someone"));
private static 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 +101,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;
}
@ -125,61 +120,60 @@ public class ChatProcessing {
mp = e.getUser().getAs(ChatPlayer.class); //May be null
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!");
if (System.nanoTime() - mp.LastMessageTime < 1000 * component.minTimeBetweenMessages().get()) { //0.1s by default
sender.sendMessage("§cYou are sending messages too fast!");
return true;
}
mp.LastMessageTime = System.nanoTime();
}
//DimensionManager.a()
//IRegistry.ae
//Bukkit.createWorld()
//MinecraftServer.reload()
//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;
if (message.startsWith(">"))
colormode = Color.Green;
// If greentext, ignore channel or player colors
ArrayList<MatchProviderBase> formatters;
if (component.allowFormatting.get()) {
formatters = addFormatters(sender -> e.shouldSendTo(ChromaGamerBase.getFromSender(sender)), component);
if (colorModeChanged && mp.RainbowPresserColorMode) { // Only overwrite channel color
if (component.allowFormatting().get()) {
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);
if (tc != null) tc.handleSpiesInit(channel, json, ChatProcessing::toJson);
for (Player p : Bukkit.getOnlinePlayers()) {
final String group;
if (player != null
@ -187,18 +181,17 @@ 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))
VanillaUtils.tellRaw(p, jsonstr);
else if (tc != null) tc.handleSpies(channel, p);
//Only sends if didn't send normally
}
} else
for (Player p : Bukkit.getOnlinePlayers())
p.sendMessage(builder.build());
VanillaUtils.tellRaw(p, jsonstr);
} 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.");
TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex);
sender.sendMessage("§cAn error occured while sending the message.");
return true;
}
DebugCommand.SendDebugMessage(
@ -207,7 +200,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 +208,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"))));
public static String toJson(TellrawPart json) {
return gson.toJson(json);
}
json.append(text(" <"));
json.append(text(user.getName()).hoverEvent(hoverEvent(SHOW_TEXT, text(user.getInfo(ChromaGamerBase.InfoTarget.MCHover)))));
json.append(text("> "));
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.substring(0, 1) + "§r|") + channel.DisplayName().get())
+ "]";
}
@ -246,7 +256,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 +275,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 +293,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()));
@ -304,15 +314,15 @@ public class ChatProcessing {
}
private static void playPingSound(Player p, @Nullable FormatterComponent component) {
if (component == null || component.notificationSound.get().length() == 0)
if (component == null || component.notificationSound().get().length() == 0)
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
else
p.playSound(p.getLocation(), component.notificationSound.get(), 1.0f,
component.notificationPitch.get());
p.playSound(p.getLocation(), component.notificationSound().get(), 1.0f,
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,42 +5,51 @@ 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.
* If you only want to disable the formatting features, set allowFormatting to false.
* If you're using another chat plugin, you should disable the whole component but that will make it impossible to use channels.
* If you're using another chat plugin, you should disable the whole component.
*/
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() {
return 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() {
return getConfig().getData("notificationSound", "");
}
/**
* The pitch of the notification sound.
*/
public IConfigData<Float> notificationPitch = getConfig().getData("notificationPitch", 1.0f);
public ConfigData<Float> notificationPitch() {
return getConfig().getData("notificationPitch", 1.0f);
}
/**
* The minimum time between messages in milliseconds.
*/
public IConfigData<Integer> minTimeBetweenMessages = getConfig().getData("minTimeBetweenMessages", 100);
public ConfigData<Integer> minTimeBetweenMessages() {
return 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 it's 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
*/
@ -129,25 +120,22 @@ public final class ChatFormatter {
sortSections(sections);
continue;
} else if (firstSection.End >= lastSection.Start && firstSection.Start <= lastSection.End) {
int middleStart = lastSection.Start;
// |----|-- |------|
// --|----| -|----|-
int middleEnd = Math.min(lastSection.End, firstSection.End);
int lastSectEnd = Math.max(lastSection.End, firstSection.End);
FormattedSection section = new FormattedSection(firstSection.Settings, middleStart, middleEnd,
int firstSectEnd = firstSection.End;
firstSection.End = lastSection.Start - 1;
int lastSectEnd = lastSection.End;
FormattedSection section = new FormattedSection(firstSection.Settings, lastSection.Start, lastSectEnd,
firstSection.Matches);
section.Settings.copyFrom(lastSection.Settings);
section.Matches.addAll(lastSection.Matches);
sections.add(i, section);
if (firstSection.End > lastSection.End) { //Copy first section info to last as the lastSection initially cuts the firstSection in half
if (firstSectEnd > lastSection.End) { //Copy first section info to last as the lastSection initially cuts the firstSection in half
lastSection.Settings = FormatSettings.builder().build();
lastSection.Settings.copyFrom(firstSection.Settings);
}
firstSection.End = middleStart - 1;
lastSection.Start = middleEnd + 1;
lastSection.End = lastSectEnd;
lastSection.Start = lastSectEnd + 1;
lastSection.End = firstSectEnd;
Predicate<FormattedSection> removeIfNeeded = s -> {
if (s.Start < 0 || s.End < 0 || s.Start > s.End) {
@ -161,11 +149,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)) {
@ -175,11 +163,21 @@ public final class ChatFormatter {
i = 0;
}
sortSections(sections);
if (i == 0) continue;
for (int j = i - 1; j <= i + 1; j++) {
if (j < sections.size() && sections.get(j).End < sections.get(j).Start) {
DebugCommand.SendDebugMessage("Removing section: " + sections.get(j));
ChatFormatUtils.sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End);
sections.remove(j);
j--;
i = 0;
}
}
}
}
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 +185,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 +212,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);
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
}
lastlink = openlink;
newtp.content(originaltext);
newtp.setText(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.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)));
}
lasttp = newtp.build();
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;
@ -27,6 +27,7 @@ public class FormatSettings {
if (field.getBoolean(settings))
field.setBoolean(this, true); //Set to true if either of them are true
} else if (field.get(settings) != null) {
//System.out.println("Setting " + field.getType() + " " + field.getName() + " from " + field.get(this) + " to " + field.get(settings));
field.set(this, field.get(settings));
}
}

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

@ -12,7 +12,7 @@ public class StringMatchProvider extends MatchProviderBase {
@ToString.Exclude
private final FormatSettings settings;
private int nextIndex = 0;
private final boolean ignoreCase;
private boolean ignoreCase;
/**
* Matches the given strings in the order given

View file

@ -6,9 +6,9 @@ import java.io.Serializable;
public final class TellrawEvent<T extends TellrawEvent.Action> implements Serializable {
private static final long serialVersionUID = -1681364161210561505L;
private final transient boolean hoverEvent;
private final T action;
private final Object value;
private transient boolean hoverEvent;
private T action;
private Object value;
private TellrawEvent(T action, String value) {
this.hoverEvent = action instanceof HoverAction;
@ -44,7 +44,7 @@ public final class TellrawEvent<T extends TellrawEvent.Action> implements Serial
public enum ClickAction implements Action {
OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command");
private final String action;
private String action;
ClickAction(String action) {
this.action = action;
@ -59,7 +59,7 @@ public final class TellrawEvent<T extends TellrawEvent.Action> implements Serial
public enum HoverAction implements Action {
SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY(
"show_entity");
private final String action;
private String action;
HoverAction(String action) {
this.action = action;

View file

@ -14,7 +14,7 @@ public final class TellrawPart implements Serializable {
private boolean underlined;
private boolean strikethrough;
private boolean obfuscated;
private final List<TellrawPart> extra = new ArrayList<>();
private List<TellrawPart> extra = new ArrayList<>();
private String text;
private TellrawEvent<TellrawEvent.HoverAction> hoverEvent;
private TellrawEvent<TellrawEvent.ClickAction> clickEvent;

View file

@ -23,7 +23,7 @@ import java.util.stream.Collectors;
})
public class FTopCommand extends ICommand2MC {
private final File playerdir = new File("TBMC/players/");
private final File playerdir = new File(TBMCPlayerBase.TBMC_PLAYERS_DIR);
private ChatPlayer[] cached;
private long lastcache = 0;
@ -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,29 +36,34 @@ 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 HashSet<CommandSender> Fs = new HashSet<>();
private UnlolCommand command;
private TBMCSystemChatEvent.BroadcastTarget unlolTarget;
private TBMCSystemChatEvent.BroadcastTarget fTarget;
private final Random random = new Random();
/**
* 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 ConfigData<String[]> laughStrings() {
return 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 ConfigData<Boolean> respect() {
return 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 ConfigData<Boolean> unlol() {
return getConfig().getData("unlol", true);
}
@Override
protected void enable() {
@ -68,7 +72,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
val pc = new PressCommand();
registerCommand(pc);
registerListener(pc);
registerCommand(command = new UnlolCommand(unlolTarget));
registerCommand(command=new UnlolCommand(unlolTarget));
registerListener(this);
registerCommand(new FTopCommand());
registerCommand(new OpmeCommand());
@ -81,21 +85,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()) {
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;
}
@ -109,13 +112,13 @@ public class FunComponent extends Component<PluginMain> implements Listener {
@EventHandler
public void onPlayerDeath(PlayerDeathEvent e) {
// MinigamePlayer mgp = Minigames.plugin.pdata.getMinigamePlayer(e.getEntity());
if (e.getDeathMessage().length() > 0 && respect.get() && random.nextBoolean()) { // Don't store Fs for NPCs
if (e.getDeathMessage().length() > 0 && respect().get() && new Random().nextBoolean()) { // Don't store Fs for NPCs
Runnable tt = () -> {
if (ActiveF) {
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,
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,
"§b" + Fs.size() + " " + (Fs.size() == 1 ? "person" : "people")
+ " paid their respects.§r", fTarget);
Fs.clear();
@ -128,8 +131,8 @@ public class FunComponent extends Component<PluginMain> implements Listener {
ActiveF = true;
Fs.clear();
FPlayer = TBMCPlayer.getPlayer(e.getEntity().getUniqueId(), ChatPlayer.class);
FPlayer.FDeaths.set(FPlayer.FDeaths.get() + 1);
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL,
FPlayer.FDeaths().set(FPlayer.FDeaths().get() + 1);
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL,
"§bPress F to pay respects.§r", fTarget);
Ftask = Bukkit.getScheduler().runTaskLaterAsynchronously(PluginMain.Instance, tt, 15 * 20);
}
@ -137,14 +140,14 @@ 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())));
if (unlol().get())
command.Lastlol.values().removeIf(lld -> lld.getLolowner().equals(event.getPlayer()));
}
@EventHandler(priority = EventPriority.LOWEST)
public void onCommandPreprocess(TBMCCommandPreprocessEvent event) {
if (event.isCancelled()) return;
if (!unlol.get()) return;
if (!unlol().get()) return;
final String cmd = event.getMessage();
// We don't care if we have arguments
if (cmd.toLowerCase().startsWith("/un")) {
@ -152,14 +155,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 +168,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;
@ -9,7 +8,6 @@ import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.ICommand2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@ -37,7 +35,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);
}
@ -46,7 +44,5 @@ public class PressCommand extends ICommand2MC implements Listener {
command = event.getCommand();
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());
}
}

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);
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

@ -11,6 +11,7 @@ import com.palmergames.bukkit.towny.object.Town;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
@ -27,7 +28,7 @@ public class NColorCommand extends UCommandBase {
Resident res;
Town town;
try {
if ((res = TownyComponent.dataSource.getResident(player.getName())) == null || !res.hasTown()
if ((res = TownyComponent.TU.getResidentMap().get(player.getName().toLowerCase())) == null || !res.hasTown()
|| (town = res.getTown()) == null) {
player.sendMessage("§cYou need to be in a town.");
return true;
@ -49,30 +50,21 @@ public class NColorCommand extends UCommandBase {
player.sendMessage("§cYour town doesn't have a color set. The town mayor can set it using /u towncolor.");
return true;
}
var component = TownColorComponent.getComponent();
byte nationColors = (byte) (component.useNationColors.get() ? 1 : 0);
if (nameparts.length < towncolors.length + nationColors) { //+1: Nation color
if (nameparts.length < towncolors.length + 1) { //+1: Nation color
player.sendMessage("§cYou need more vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")"); //Nation color
return true;
}
if (nameparts.length > (towncolors.length + nationColors) * 2) {
if (nameparts.length > (towncolors.length + 1) * 2) {
player.sendMessage("§cYou have waay too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")");
return true;
}
if (nameparts.length > towncolors.length + nationColors) {
if (nameparts.length > towncolors.length + 1) {
player.sendMessage("§cYou have too many vertical lines (|) or colons (:) in your name. (Should have " + (towncolors.length - 1 + 1) + ")");
return true;
}
var cp = ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class);
var list = Arrays.stream(nameparts).map(String::length).collect(Collectors.toList());
if (list.contains(0)) {
player.sendMessage("§cAll colors need to be represented in your name. (Use as Test|name|123 instead of |Testname123|)");
return true;
}
var clist = cp.NameColorLocations.get(); // No byte[], no TIntArrayList
clist.clear();
clist.addAll(list);
TownColorComponent.updatePlayerColors(player, cp);
ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations()
.set(new ArrayList<>(Arrays.stream(nameparts).map(String::length).collect(Collectors.toList()))); // No byte[], no TIntArrayList
TownColorComponent.updatePlayerColors(player);
player.sendMessage("§bName colors set: " + player.getDisplayName());
return true;
}

View file

@ -3,6 +3,7 @@ package buttondevteam.chat.components.towncolors;
import buttondevteam.chat.commands.ucmds.UCommandBase;
import buttondevteam.chat.components.towncolors.admin.TownColorCommand;
import buttondevteam.chat.components.towny.TownyComponent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.CustomTabCompleteMethod;
@ -20,19 +21,21 @@ import org.bukkit.entity.Player;
public class NationColorCommand extends UCommandBase {
@Command2.Subcommand
public boolean def(Player player, String color) {
String msg = "§cYou need to be the king of a nation to set it's colors.";
Resident res;
if (!(TownyComponent.TU.getResidentMap().containsKey(player.getName().toLowerCase())
&& (res = TownyComponent.TU.getResidentMap().get(player.getName().toLowerCase())).isKing())) {
player.sendMessage("§cYou need to be the king of a nation to set it's colors.");
return true;
}
final Nation n;
try {
Resident res = TownyComponent.dataSource.getResident(player.getName());
if (!res.isKing()) {
player.sendMessage(msg);
return true;
}
final Nation n = res.getTown().getNation();
return buttondevteam.chat.components.towncolors.admin.NationColorCommand.SetNationColor(player, n, color);
n = res.getTown().getNation();
} catch (NotRegisteredException e) {
player.sendMessage(msg);
TBMCCoreAPI.SendException("Failed to set nation color for player " + player + "!", e);
player.sendMessage("§cCouldn't find your town/nation... Error reported.");
return true;
}
return buttondevteam.chat.components.towncolors.admin.NationColorCommand.SetNationColor(player, n, color);
}
@CustomTabCompleteMethod(param = "color")

View file

@ -2,6 +2,7 @@ package buttondevteam.chat.components.towncolors;
import buttondevteam.chat.commands.ucmds.UCommandBase;
import buttondevteam.chat.components.towny.TownyComponent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.CustomTabCompleteMethod;
@ -17,31 +18,33 @@ import org.bukkit.entity.Player;
"This command allows setting a color for a town.", //
"The town will be shown with this color on Dynmap and all players in the town will appear in chat with these colors.", //
"The colors will split the name evenly but residents can override that with /u ncolor.", //
})
}) // TODO: /u u when annotation not present
@RequiredArgsConstructor
public class TownColorCommand extends UCommandBase {
private final TownColorComponent component;
@Command2.Subcommand
public boolean def(Player player, String... colornames) {
String msg = "§cYou need to be the mayor of a town to set its colors.";
try {
Resident res = TownyComponent.dataSource.getResident(player.getName());
if (!res.isMayor()) {
player.sendMessage(msg);
Resident res;
if (!(TownyComponent.TU.getResidentMap().containsKey(player.getName().toLowerCase())
&& (res = TownyComponent.TU.getResidentMap().get(player.getName().toLowerCase())).isMayor())) {
player.sendMessage("§cYou need to be the mayor of a town to set its colors.");
return true;
}
val cc = component.colorCount.get();
val cc = component.colorCount().get();
if (colornames.length > cc) {
player.sendMessage("You can only use " + cc + " color" + (cc > 1 ? "s" : "") + ".");
return true;
}
final Town t = res.getTown();
return buttondevteam.chat.components.towncolors.admin.TownColorCommand.SetTownColor(player, t, colornames);
final Town t;
try {
t = res.getTown();
} catch (NotRegisteredException e) {
player.sendMessage(msg);
TBMCCoreAPI.SendException("Failed to set town color for player " + player + "!", e);
player.sendMessage("§cCouldn't find your town... Error reported.");
return true;
}
return buttondevteam.chat.components.towncolors.admin.TownColorCommand.SetTownColor(player, t, colornames);
}
@CustomTabCompleteMethod(param = "colornames")

View file

@ -8,13 +8,12 @@ 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 buttondevteam.lib.player.TBMCPlayerJoinEvent;
import com.earth2me.essentials.User;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Resident;
import lombok.Getter;
import lombok.val;
import org.bukkit.Bukkit;
@ -22,9 +21,7 @@ import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
import org.dynmap.towny.DTBridge;
@ -44,22 +41,26 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
/**
* Names lowercased
*/
public static final Map<String, Color[]> TownColors = new HashMap<>();
public static Map<String, Color[]> TownColors = new HashMap<>();
/**
* Names lowercased - nation color gets added to town colors when needed
*/
public static final Map<String, Color> NationColor = new HashMap<>();
public static Map<String, Color> NationColor = new HashMap<>();
/**
* 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.
* The amount of town colors allowed. If more than one is used, 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 ConfigData<Byte> colorCount() {
return 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 ConfigData<Boolean> useNationColors() {
return getConfig().getData("useNationColors", true);
}
@Getter
private static TownColorComponent component;
@ -71,7 +72,7 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
Consumer<ConfigurationSection> loadTC = cs -> TownColorComponent.TownColors.putAll(cs.getValues(true).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, v -> ((List<String>) v.getValue()).stream()
.map(Color::valueOf).toArray(Color[]::new))));
boolean usenc = useNationColors.get();
boolean usenc = useNationColors().get();
Consumer<ConfigurationSection> loadNC = ncs ->
TownColorComponent.NationColor.putAll(ncs.getValues(true).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, v -> Color.valueOf((String) v.getValue()))));
@ -84,17 +85,17 @@ 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.TU.getTownsMap().containsKey(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.TU.getNationsMap().containsKey(n)); // Removes nation colors for deleted/renamed nations
initDynmap();
registerCommand(new TownColorCommand(this));
if (useNationColors.get())
if (useNationColors().get())
registerCommand(new NationColorCommand());
registerCommand(new buttondevteam.chat.components.towncolors.admin.TownColorCommand());
if (useNationColors.get())
if (useNationColors().get())
registerCommand(new buttondevteam.chat.components.towncolors.admin.NationColorCommand());
registerCommand(new TCCount());
registerCommand(new NColorCommand());
@ -106,10 +107,9 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
protected void disable() {
getConfig().getConfig().createSection("towncolors", TownColors.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
v -> Arrays.stream(v.getValue()).map(Enum::toString).toArray(String[]::new))));
if (useNationColors.get())
if (useNationColors().get())
getConfig().getConfig().createSection("nationcolors", NationColor.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
v -> v.getValue().toString())));
getConfig().signalChange();
}
private void initDynmap() {
@ -119,16 +119,16 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
return;
for (val entry : TownColors.entrySet()) {
try {
val town = TownyComponent.dataSource.getTown(entry.getKey());
val town = TownyComponent.TU.getTownsMap().get(entry.getKey());
Nation nation;
Color nc;
if (!useNationColors.get())
if (!useNationColors().get())
nc = null;
else if (!town.hasNation() || (nation = town.getNation()) == null || (nc = NationColor.get(nation.getName().toLowerCase())) == null)
nc = Color.White;
setTownColor(dtp, buttondevteam.chat.components.towncolors.admin.TownColorCommand.getTownNameCased(entry.getKey()), entry.getValue(), nc);
} catch (Exception e) {
TBMCCoreAPI.SendException("Error while setting town color for town " + entry.getKey() + "!", e, this);
TBMCCoreAPI.SendException("Error while setting town color for town " + entry.getKey() + "!", e);
}
}
});
@ -147,7 +147,7 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
DTBridge.setTownColor(dtp, town, c2i.apply(nationcolor == null ? colors[0] : nationcolor),
c2i.apply(colors.length > 1 && nationcolor != null ? colors[1] : colors[0]));
} catch (Exception e) {
TBMCCoreAPI.SendException("Failed to set town color for town " + town + "!", e, component);
TBMCCoreAPI.SendException("Failed to set town color for town " + town + "!", e);
}
}
@ -156,7 +156,7 @@ 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());
val res = TownyComponent.TU.getResidentMap().get(player.getName().toLowerCase());
if (res == null || !res.hasTown())
return name;
try {
@ -178,8 +178,8 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
len = name.length() / (clrs.length+1);
else
len = name.length() / clrs.length;*/
boolean usenc = component.useNationColors.get();
val nclar = cp.NameColorLocations.get();
boolean usenc = component.useNationColors().get();
val nclar = cp.NameColorLocations().get();
int[] ncl = nclar == null ? null : nclar.stream().mapToInt(Integer::intValue).toArray();
if (ncl != null && (Arrays.stream(ncl).sum() != name.length() || ncl.length != clrs.length + (usenc ? 1 : 0))) //+1: Nation color
ncl = null; // Reset if name length changed
@ -201,14 +201,14 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
/**
* Checks if the component is enabled
*/
public static void updatePlayerColors(Player player) { //Probably while ingame (/u ncolor - not anymore)
public static void updatePlayerColors(Player player) { //Probably while ingame (/u ncolor)
updatePlayerColors(player, ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class));
}
/**
* Checks if the component is enabled
*/
public static void updatePlayerColors(Player player, ChatPlayer cp) { //Probably at join - nop, nicknames
private static void updatePlayerColors(Player player, ChatPlayer cp) { //Probably at join - nop, nicknames
if (!ComponentManager.isEnabled(TownColorComponent.class))
return;
User user = PluginMain.essentials.getUser(player);
@ -217,8 +217,8 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
cp.FlairUpdate(); //Update in list
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(PlayerJoinEvent event) {
updatePlayerColors(event.getPlayer(), TBMCPlayer.getPlayer(event.getPlayer().getUniqueId(), ChatPlayer.class));
@EventHandler
public void onPlayerJoin(TBMCPlayerJoinEvent event) {
updatePlayerColors(event.getPlayer(), event.GetPlayer().asPluginPlayer(ChatPlayer.class));
}
}

View file

@ -61,7 +61,7 @@ public class TownyListener implements Listener {
@EventHandler
public void onNationRename(RenameNationEvent event) {
if (!TownColorComponent.getComponent().useNationColors.get()) return;
if (!TownColorComponent.getComponent().useNationColors().get()) return;
val clrs = TownColorComponent.NationColor.remove(event.getOldName().toLowerCase());
if (clrs != null)
TownColorComponent.NationColor.put(event.getNation().getName().toLowerCase(), clrs);
@ -69,25 +69,25 @@ public class TownyListener implements Listener {
@EventHandler //Gets called on town load as well
public void onNationJoin(NationAddTownEvent event) {
if (!TownColorComponent.getComponent().useNationColors.get()) return;
if (!TownColorComponent.getComponent().useNationColors().get()) return;
updateTownMembers(event.getTown());
}
@EventHandler
public void onNationLeave(NationRemoveTownEvent event) {
if (!TownColorComponent.getComponent().useNationColors.get()) return;
if (!TownColorComponent.getComponent().useNationColors().get()) return;
updateTownMembers(event.getTown()); //The town still has it's colours
}
@EventHandler
public void onNationDelete(DeleteNationEvent event) {
if (!TownColorComponent.getComponent().useNationColors.get()) return;
if (!TownColorComponent.getComponent().useNationColors().get()) return;
TownColorComponent.NationColor.remove(event.getNationName().toLowerCase());
}
@EventHandler
public void onNationCreate(NewNationEvent event) {
if (!TownColorComponent.getComponent().useNationColors.get()) return;
if (!TownColorComponent.getComponent().useNationColors().get()) return;
Player p = Bukkit.getPlayer(event.getNation().getCapital().getMayor().getName());
if (p != null)
p.sendMessage("§6Use /u nationcolor to set a color for the nation.");

View file

@ -23,7 +23,7 @@ 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);
final Nation n = TownyComponent.TU.getNationsMap().get(nation.toLowerCase());
if (n == null) {
sender.sendMessage("§cThe nation '" + nation + "' cannot be found.");
return true;
@ -38,7 +38,7 @@ public class NationColorCommand extends AdminCommandBase {
@CustomTabCompleteMethod(param = "nation")
public Iterable<String> def() {
return TownyComponent.dataSource.getNations().stream().map(TownyObject::getName)::iterator;
return TownyComponent.TU.getDataSource().getNations().stream().map(TownyObject::getName)::iterator;
}
public static boolean SetNationColor(CommandSender sender, Nation nation, String color) {

View file

@ -15,7 +15,7 @@ public class TCCount extends AdminCommandBase {
@Command2.Subcommand
public boolean def(CommandSender sender, byte count) {
val comp = TownColorComponent.getComponent();
comp.colorCount.set(count);
comp.colorCount().set(count);
sender.sendMessage("Color count set to " + count);
return true;
}

View file

@ -25,18 +25,14 @@ import java.util.stream.Collectors;
"The town will be shown with this color on Dynmap and all players in the town will appear in chat with these colors.", //
"The colors will split the name evenly.", //
})
public class TownColorCommand extends AdminCommandBase {
public class TownColorCommand extends AdminCommandBase { //TODO: Command path aliases
@Command2.Subcommand
public boolean def(CommandSender sender, String town, String... colornames) {
if (TownyComponent.dataSource.getTown(town) == null) {
sender.sendMessage("§cThe town '" + town + "' cannot be found.");
return true;
}
Town targetTown = TownyComponent.dataSource.getTown(town);
if (targetTown == null) {
if (!TownyComponent.TU.getTownsMap().containsKey(town.toLowerCase())) {
sender.sendMessage("§cThe town '" + town + "' cannot be found.");
return true;
}
Town targetTown = TownyComponent.TU.getTownsMap().get(town.toLowerCase());
return SetTownColor(sender, targetTown, colornames);
}
@ -47,7 +43,7 @@ public class TownColorCommand extends AdminCommandBase {
@CustomTabCompleteMethod(param = "town")
public Iterable<String> def() {
return TownyComponent.dataSource.getTowns().stream().map(TownyObject::getName)::iterator;
return TownyComponent.TU.getDataSource().getTowns().stream().map(TownyObject::getName)::iterator;
}
public static boolean SetTownColor(CommandSender sender, Town town, String[] colors) {
@ -59,7 +55,7 @@ public class TownColorCommand extends AdminCommandBase {
clrs[i] = c.get();
}
Color tnc;
boolean usenc = TownColorComponent.getComponent().useNationColors.get();
boolean usenc = TownColorComponent.getComponent().useNationColors().get();
if (usenc) {
try {
tnc = TownColorComponent.NationColor.get(town.getNation().getName().toLowerCase());
@ -72,7 +68,7 @@ public class TownColorCommand extends AdminCommandBase {
Color nc;
if (usenc) {
try {
nc = TownColorComponent.NationColor.get(TownyComponent.dataSource.getTown(other.getKey()).getNation().getName().toLowerCase());
nc = TownColorComponent.NationColor.get(TownyComponent.TU.getTownsMap().get(other.getKey()).getNation().getName().toLowerCase());
} catch (Exception e) { //Too lazy for lots of null-checks and it may throw exceptions anyways
nc = null;
}
@ -116,11 +112,7 @@ public class TownColorCommand extends AdminCommandBase {
}
public static String getTownNameCased(String name) {
val town = TownyComponent.dataSource.getTown(name);
if (town == null) {
return null;
}
return town.getName();
return TownyComponent.TU.getTownsMap().get(name.toLowerCase()).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,33 +1,33 @@
package buttondevteam.chat.components.towny;
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.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.function.Consumer;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* This component manages the town and nation chat. It's also needed for the TownColorComponent.
* It provides the TC and NC channels, and posts Towny messages (global, town, nation) to the correct channels for other platforms like Discord.
* 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 TownyUniverse TU;
private static ArrayList<String> Towns;
private static ArrayList<String> Nations;
@ -36,12 +36,12 @@ 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(
TU = TownyUniverse.getInstance();
Towns = TU.getTownsMap().values().stream().map(Town::getName).collect(Collectors.toCollection(ArrayList::new)); // Creates a snapshot of towns, new towns will be added when needed
Nations = TU.getNationsMap().values().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 +51,30 @@ 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 void handleSpiesInit(Channel channel, TellrawPart json, Function<TellrawPart, String> toJson) {
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]"));
jsonstr = toJson.apply(json);
}
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;
}
if (res.hasMode("spy"))
p.sendMessage(jsonstr.build());
private String jsonstr;
public void handleSpies(Channel channel, Player p) {
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
if (Optional.ofNullable(TU.getResidentMap().get(p.getName().toLowerCase()))
.filter(r -> r.hasMode("spy")).isPresent())
VanillaUtils.tellRaw(p, jsonstr);
}
}
/**
* 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 = TU.getResidentMap().get(sender.getName().toLowerCase());
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,27 +7,31 @@ 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 buttondevteam.lib.player.TBMCPlayerJoinEvent;
import buttondevteam.lib.player.TBMCPlayerLoadEvent;
import buttondevteam.lib.player.TBMCPlayerSaveEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Timer;
public class PlayerJoinLeaveListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
ChatPlayer cp = TBMCPlayerBase.getPlayer(p.getUniqueId(), ChatPlayer.class);
@EventHandler
public void onPlayerLoad(TBMCPlayerLoadEvent e) {
ChatPlayer cp = e.GetPlayer().asPluginPlayer(ChatPlayer.class);
cp.FlairUpdate();
}
@EventHandler
public void onPlayerTBMCJoin(TBMCPlayerJoinEvent e) {
ChatPlayer cp = e.GetPlayer().asPluginPlayer(ChatPlayer.class);
Player p = e.getPlayer();
if (ComponentManager.isEnabled(FlairComponent.class)) {
if (!cp.FlairState.get().equals(FlairStates.NoComment)) {
if (!cp.FlairState().get().equals(FlairStates.NoComment)) {
FlairComponent.ConfirmUserMessage(cp);
Timer timer = new Timer();
PlayerJoinTimerTask tt = new PlayerJoinTimerTask() {
@ -51,10 +55,14 @@ public class PlayerJoinLeaveListener implements Listener {
nwithoutformatting = nwithoutformatting.replace("§" + nwithoutformatting.charAt(index + 1), "");
} else
nwithoutformatting = p.getName();
PlayerListener.nicknames.forcePut(nwithoutformatting.toLowerCase(), p.getUniqueId());
PlayerListener.nicknames.forcePut(nwithoutformatting.toLowerCase(), p.getUniqueId()); //TODO: FormatterComponent
if (PluginMain.Instance.storeChatHistory.get())
HistoryCommand.showHistory(ChromaGamerBase.getFromSender(e.getPlayer()), null);
if (PluginMain.Instance.storeChatHistory().get())
HistoryCommand.showHistory(e.getPlayer(), null);
}
@EventHandler
public void onPlayerSave(TBMCPlayerSaveEvent e) {
}
@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;
@ -32,7 +31,7 @@ public class PlayerListener implements Listener {
/**
* Does not contain format codes, lowercased
*/
public static final BiMap<String, UUID> nicknames = HashBiMap.create();
public static BiMap<String, UUID> nicknames = HashBiMap.create();
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerChat(AsyncPlayerChatEvent event) {
@ -54,18 +53,21 @@ public class PlayerListener implements Listener {
@EventHandler
public void onGetInfo(TBMCPlayerGetInfoEvent e) {
ChatPlayer cp = e.getPlayer().getAs(ChatPlayer.class);
try (ChatPlayer cp = e.getPlayer().getAs(ChatPlayer.class)) {
if (cp == null)
return;
e.addInfo("Minecraft name: " + cp.getPlayerName());
if (cp.UserName.get() != null && cp.UserName.get().length() > 0)
e.addInfo("Reddit name: " + cp.UserName.get());
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)) {
final String flair = cp.GetFormattedFlair(e.getTarget() != InfoTarget.MCCommand);
if (flair.length() > 0)
e.addInfo("/r/TheButton flair: " + flair);
}
e.addInfo(String.format("Respect: %.2f", cp.getF()));
} catch (Exception ex) {
TBMCCoreAPI.SendException("Error while providing chat info for player " + e.getPlayer().getFileName(), ex);
}
}
private long lastError = 0;
@ -75,18 +77,18 @@ 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);
ChatUtils.sendChatMessage(e, s -> "§c!§r" + s);
TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex);
}
}
@ -94,9 +96,9 @@ public class PlayerListener implements Listener {
public void onNickChange(NickChangeEvent e) {
String nick = e.getValue();
if (nick == null)
nicknames.inverse().remove(e.getController().getBase().getUniqueId()); //EssentialsX has it swapped
nicknames.inverse().remove(e.getAffected().getBase().getUniqueId());
else
nicknames.inverse().forcePut(e.getController().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase());
nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase());
Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
TownColorComponent.updatePlayerColors(e.getAffected().getBase()); //Won't fire this event again

View file

@ -4,7 +4,7 @@ import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.Plugin;
import org.dynmap.DynmapCommonAPI;
import org.dynmap.bukkit.DynmapPlugin;
import org.dynmap.markers.MarkerAPI;
import java.lang.reflect.Constructor;
@ -35,7 +35,7 @@ public class DTBridge {
Constructor<?> c = cl.getDeclaredConstructor(FileConfiguration.class, String.class, MarkerAPI.class);
c.setAccessible(true);
style = c.newInstance(dtp.getConfig(), "custstyle." + townname,
((DynmapCommonAPI) Bukkit.getPluginManager().getPlugin("dynmap")).getMarkerAPI());
((DynmapPlugin) Bukkit.getPluginManager().getPlugin("dynmap")).getMarkerAPI());
map.put(townname, style);
}
set(cl, style, "fillcolor", fillcolor);

View file

@ -1,14 +1,18 @@
name: Chroma-Chat
main: buttondevteam.chat.PluginMain
version: '${noprefix.version}'
version: '4.0'
commands:
u:
description: The main command for Chroma-Chat.
description: Auto-flair system. Accept or ignore flair.
ooc:
description: Send message Out-of-Character.
alias: nrp
unlol:
description: Unlaugh the last laugh.
alias: unlaugh
mwiki:
description: Search the wiki.
dontrunthiscmd: null
tableflip:
description: Flip a table.
unflip:
@ -26,17 +30,15 @@ commands:
description: Lenny face.
ftop:
description: Top respect.
me:
description: Me command with Chroma support.
author: NorbiPeti
depend:
- Essentials
- Vault
- Chroma-Core
softdepend:
- Dynmap-Towny
- Towny
- dynmap
- Essentials
- Vault
- ChromaCore
soft-depend:
- Minigames
- Dynmap-Towny
- Towny
permissions:
tbmc.badge.gold:
description: Gives a patron badge.
@ -44,4 +46,3 @@ permissions:
tbmc.badge.diamond:
description: Gives a cool patron badge.
default: false
api-version: '1.13'

View file

@ -1,129 +1,103 @@
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.chat.Color;
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);
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);
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(" 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(" and other "),
whiteBoldItalic.apply("greatness").decorate(UNDERLINED),
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)));
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());
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;
this.extras = expectedextras;
}
private ChatFormatIT setRainbowMode() {
@ -133,16 +107,18 @@ public class ChatFormatIT {
@Test
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());
System.out.println("Testing: " + message);
// System.out.println(ChatProcessing.toJson(tp));
final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
// System.out.println("Raw: " + ChatProcessing.toJson(expectedtp));
for (TellrawPart extra : extras)
expectedtp.addExtra(extra);
Assert.assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp));
}
}