1.14 support, fixes #105
34 changed files with 1232 additions and 945 deletions
|
@ -1,12 +1,13 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_13_PREVIEW">
|
||||||
<output url="file://$MODULE_DIR$/target/classes" />
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
@ -24,11 +25,19 @@
|
||||||
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
||||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.19.0-GA" level="project" />
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.19.0-GA" level="project" />
|
||||||
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||||
<orderEntry type="library" name="Maven: net.ess3:Essentials:2.13.1" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:EssentialsX:2.17.1" level="project" />
|
||||||
<orderEntry type="library" name="Maven: com.github.TBMCPlugins.ButtonCore:Towny:8d3b6b6" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: io.papermc:paperlib:1.0.2" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.milkbowl:VaultAPI:master-68f14eca20-1" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:NMSProvider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:UpdatedMetaProvider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:1_8_R1Provider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:1_8_R2Provider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:LegacyProvider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:ReflectionProvider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:FlattenedProvider:2.17.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: com.palmergames.bukkit.towny:Towny:0.95.0.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.milkbowl:VaultAPI:master-4c248aad62-1" level="project" />
|
||||||
<orderEntry type="library" name="Maven: org.bukkit:bukkit:1.13.1-R0.1-SNAPSHOT" level="project" />
|
<orderEntry type="library" name="Maven: org.bukkit:bukkit:1.13.1-R0.1-SNAPSHOT" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.16.16" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.10" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot:1.12.2-R0.1-SNAPSHOT" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot:1.12.2-R0.1-SNAPSHOT" level="project" />
|
||||||
<orderEntry type="library" name="Maven: com.github.webbukkit:Dynmap-Towny:master-0.60-g924051d-7" level="project" />
|
<orderEntry type="library" name="Maven: com.github.webbukkit:Dynmap-Towny:master-0.60-g924051d-7" level="project" />
|
||||||
<orderEntry type="library" name="Maven: com.github.webbukkit:Dynmap:v2.5" level="project" />
|
<orderEntry type="library" name="Maven: com.github.webbukkit:Dynmap:v2.5" level="project" />
|
||||||
|
@ -39,5 +48,7 @@
|
||||||
<orderEntry type="library" name="Maven: org.anjocaido:EssentialsGroupManager:2.10.1" level="project" />
|
<orderEntry type="library" name="Maven: org.anjocaido:EssentialsGroupManager:2.10.1" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.logging.log4j:log4j-core:2.8.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.logging.log4j:log4j-api:2.8.1" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -11,6 +11,7 @@ language: java
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- oraclejdk8
|
||||||
sudo: true
|
sudo: true
|
||||||
|
dist: trusty # Needed for Java 8, although we might not need Java 8
|
||||||
deploy:
|
deploy:
|
||||||
# deploy develop to the staging environment
|
# deploy develop to the staging environment
|
||||||
- provider: script
|
- provider: script
|
||||||
|
|
97
pom.xml
97
pom.xml
|
@ -1,6 +1,11 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.github.TBMCPlugins.ButtonCore</groupId>
|
||||||
|
<artifactId>CorePOM</artifactId>
|
||||||
|
<version>master-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<name>The Button Minecraft Chat Plugin</name>
|
<name>The Button Minecraft Chat Plugin</name>
|
||||||
<description>The Button Minecraft Chat Plugin</description>
|
<description>The Button Minecraft Chat Plugin</description>
|
||||||
|
@ -26,18 +31,10 @@
|
||||||
</resources>
|
</resources>
|
||||||
<finalName>ButtonChat</finalName>
|
<finalName>ButtonChat</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.3</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.4.2</version>
|
<version>3.2.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
|
@ -48,7 +45,6 @@
|
||||||
<artifactSet>
|
<artifactSet>
|
||||||
<includes>
|
<includes>
|
||||||
<include>net.sourceforge.htmlcleaner:htmlcleaner</include>
|
<include>net.sourceforge.htmlcleaner:htmlcleaner</include>
|
||||||
<include>org.javassist:javassist</include>
|
|
||||||
</includes>
|
</includes>
|
||||||
</artifactSet>
|
</artifactSet>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -151,14 +147,14 @@
|
||||||
<id>jitpack</id>
|
<id>jitpack</id>
|
||||||
<url>https://jitpack.io/</url>
|
<url>https://jitpack.io/</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>Essentials</id>
|
<id>ess-repo</id>
|
||||||
<url>http://repo.ess3.net/content/repositories/essrel/</url>
|
<url>https://ci.ender.zone/plugin/repository/everything/</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<!-- <repository>
|
||||||
<id>Minigames</id>
|
<id>Minigames</id>
|
||||||
<url>http://maven.addstar.com.au/artifactory/release</url>
|
<url>http://maven.addstar.com.au/artifactory/release</url>
|
||||||
</repository>
|
</repository> -->
|
||||||
<!-- <repository>
|
<!-- <repository>
|
||||||
<id>vault-repo</id>
|
<id>vault-repo</id>
|
||||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||||
|
@ -169,7 +165,7 @@
|
||||||
<id>projectlombok.org</id>
|
<id>projectlombok.org</id>
|
||||||
<url>http://projectlombok.org/mavenrepo</url>
|
<url>http://projectlombok.org/mavenrepo</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
|
@ -193,16 +189,18 @@
|
||||||
<artifactId>reflections</artifactId>
|
<artifactId>reflections</artifactId>
|
||||||
<version>0.9.10</version>
|
<version>0.9.10</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.ess3</groupId>
|
<groupId>net.ess3</groupId>
|
||||||
<artifactId>Essentials</artifactId>
|
<artifactId>EssentialsX</artifactId>
|
||||||
<version>2.13.1</version>
|
<version>2.17.1</version>
|
||||||
</dependency>
|
<scope>provided</scope>
|
||||||
<dependency>
|
</dependency>
|
||||||
<groupId>com.github.TBMCPlugins.ButtonCore</groupId>
|
<dependency>
|
||||||
<artifactId>Towny</artifactId>
|
<groupId>com.palmergames.bukkit.towny</groupId>
|
||||||
<version>8d3b6b6</version>
|
<artifactId>Towny</artifactId>
|
||||||
</dependency>
|
<version>0.95.0.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<!-- <dependency> <groupId>au.com.mineauz</groupId> <artifactId>Minigames</artifactId>
|
<!-- <dependency> <groupId>au.com.mineauz</groupId> <artifactId>Minigames</artifactId>
|
||||||
<version>1.8.0</version> </dependency> -->
|
<version>1.8.0</version> </dependency> -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -211,18 +209,26 @@
|
||||||
<version>master-SNAPSHOT</version>
|
<version>master-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
||||||
<groupId>org.projectlombok</groupId>
|
<dependency>
|
||||||
<artifactId>lombok</artifactId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<version>1.16.16</version>
|
<artifactId>lombok</artifactId>
|
||||||
<scope>provided</scope>
|
<version>1.18.10</version>
|
||||||
</dependency>
|
<scope>provided</scope>
|
||||||
<dependency>
|
</dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
|
||||||
<artifactId>spigot</artifactId>
|
<dependency>
|
||||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
<groupId>org.spigotmc</groupId>
|
||||||
<scope>provided</scope>
|
<artifactId>spigot</artifactId>
|
||||||
</dependency>
|
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot</artifactId>
|
||||||
|
<version>1.14.4-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency> -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.webbukkit</groupId>
|
<groupId>com.github.webbukkit</groupId>
|
||||||
<artifactId>Dynmap-Towny</artifactId>
|
<artifactId>Dynmap-Towny</artifactId>
|
||||||
|
@ -240,7 +246,14 @@
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
<!-- Included in vanilla minecraft's JAR -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>2.8.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
<artifactId>ButtonChat</artifactId>
|
<artifactId>ButtonChat</artifactId>
|
||||||
<organization>
|
<organization>
|
||||||
<name>TBMCPlugins</name>
|
<name>TBMCPlugins</name>
|
||||||
|
|
|
@ -1,333 +0,0 @@
|
||||||
package buttondevteam.chat;
|
|
||||||
|
|
||||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
|
||||||
import buttondevteam.chat.components.chatonly.ChatOnlyComponent;
|
|
||||||
import buttondevteam.chat.components.fun.FunComponent;
|
|
||||||
import buttondevteam.chat.components.towny.TownyComponent;
|
|
||||||
import buttondevteam.chat.formatting.ChatFormatter;
|
|
||||||
import buttondevteam.chat.formatting.TellrawEvent;
|
|
||||||
import buttondevteam.chat.formatting.TellrawPart;
|
|
||||||
import buttondevteam.chat.formatting.TellrawSerializer;
|
|
||||||
import buttondevteam.chat.listener.PlayerListener;
|
|
||||||
import buttondevteam.core.ComponentManager;
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
|
||||||
import buttondevteam.lib.TBMCChatEvent;
|
|
||||||
import buttondevteam.lib.TBMCChatEventBase;
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import buttondevteam.lib.chat.Color;
|
|
||||||
import buttondevteam.lib.chat.Priority;
|
|
||||||
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.Lists;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import lombok.val;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.scoreboard.Objective;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class ChatProcessing {
|
|
||||||
private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null");
|
|
||||||
private static final Pattern CYAN_PATTERN = Pattern.compile("cyan");
|
|
||||||
private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\");
|
|
||||||
private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console"));
|
|
||||||
private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)");
|
|
||||||
private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),&]+(?:#[\\w]+)?)");
|
|
||||||
public static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+");
|
|
||||||
private static final Pattern UNDERLINED_PATTERN = Pattern.compile("_");
|
|
||||||
private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*");
|
|
||||||
private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*");
|
|
||||||
private static final Pattern CODE_PATTERN = Pattern.compile("`");
|
|
||||||
private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]]+)]\\(([^()]+)\\)");
|
|
||||||
private static final Pattern SOMEONE_PATTERN = Pattern.compile("@someone"); //TODO
|
|
||||||
private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~");
|
|
||||||
private static final Pattern SPOILER_PATTERN = Pattern.compile("\\|\\|");
|
|
||||||
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 boolean pingedconsole = false;
|
|
||||||
|
|
||||||
public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build();
|
|
||||||
|
|
||||||
private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList(
|
|
||||||
ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
|
||||||
.priority(Priority.High).build(),
|
|
||||||
ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(),
|
|
||||||
ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
|
|
||||||
.build(),
|
|
||||||
ChatFormatter.builder().regex(STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
|
||||||
.build(),
|
|
||||||
ChatFormatter.builder().regex(SPOILER_PATTERN).obfuscated(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
|
||||||
.onmatch((match, cf, fs) -> {
|
|
||||||
cf.setHoverText(match);
|
|
||||||
return match;
|
|
||||||
}).build(),
|
|
||||||
ESCAPE_FORMATTER, ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
|
|
||||||
ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder, section) -> {
|
|
||||||
if (!pingedconsole) {
|
|
||||||
System.out.print("\007");
|
|
||||||
pingedconsole = true; // Will set it to false in ProcessChat
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
}).priority(Priority.High).build(),
|
|
||||||
|
|
||||||
ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1")
|
|
||||||
.priority(Priority.High).build(),
|
|
||||||
ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55
|
|
||||||
ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
|
|
||||||
.build(),
|
|
||||||
ChatFormatter.builder().regex(MASKED_LINK_PATTERN).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 "";
|
|
||||||
builder.setOpenlink(link);
|
|
||||||
return text;
|
|
||||||
}).type(ChatFormatter.Type.Excluder).build(),
|
|
||||||
ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build());
|
|
||||||
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"};
|
|
||||||
public static final String MCORIGIN = "Minecraft"; //Shouldn't change, like ever - TBMCPlayer.getFolderForType(TBMCPlayer.class) capitalized
|
|
||||||
|
|
||||||
private ChatProcessing() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean ProcessChat(TBMCChatEvent e) {
|
|
||||||
Channel channel = e.getChannel();
|
|
||||||
CommandSender sender = e.getSender();
|
|
||||||
String message = e.getMessage();
|
|
||||||
long processstart = System.nanoTime();
|
|
||||||
Player player = (sender instanceof Player ? (Player) sender : null);
|
|
||||||
User user = PluginMain.essentials.getUser(player);
|
|
||||||
|
|
||||||
if (player != null) {
|
|
||||||
user.updateActivity(true); //Could talk in a private channel, so broadcast
|
|
||||||
if (user.isMuted())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
doFunStuff(sender, e, message);
|
|
||||||
|
|
||||||
ChatPlayer mp;
|
|
||||||
if (player != null)
|
|
||||||
mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class);
|
|
||||||
else //Due to the online player map, getPlayer() can be more efficient than getAs()
|
|
||||||
mp = e.getUser().getAs(ChatPlayer.class); //May be null
|
|
||||||
|
|
||||||
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<ChatFormatter> formatters = addFormatters(colormode);
|
|
||||||
if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
|
|
||||||
final AtomicInteger rpc = new AtomicInteger(0);
|
|
||||||
formatters.add(ChatFormatter.builder().regex(WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> {
|
|
||||||
cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
|
|
||||||
return match;
|
|
||||||
}).build());
|
|
||||||
}
|
|
||||||
pingedconsole = false; // Will set it to true onmatch (static constructor)
|
|
||||||
final String channelidentifier = getChannelID(channel, e.getOrigin());
|
|
||||||
|
|
||||||
TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin());
|
|
||||||
long combinetime = System.nanoTime();
|
|
||||||
ChatFormatter.Combine(formatters, message, json);
|
|
||||||
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()) {
|
|
||||||
Objective obj = PluginMain.SB.getObjective(channel.ID);
|
|
||||||
int score = -1;
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
|
||||||
final int mcScore;
|
|
||||||
if (player != null
|
|
||||||
&& PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player)))
|
|
||||||
mcScore = -1; // Don't send the message to them
|
|
||||||
else
|
|
||||||
mcScore = VanillaUtils.getMCScoreIfChatOn(p, e);
|
|
||||||
obj.getScore(p.getName())
|
|
||||||
.setScore(p.getUniqueId().equals(player == null ? null : player.getUniqueId()) // p.UniqueID==player?.UniqueID
|
|
||||||
? score = mcScore : mcScore);
|
|
||||||
}
|
|
||||||
if (score == -1) // Even if the player object isn't null, it may not be in OnlinePlayers
|
|
||||||
score = e.getMCScore(sender);
|
|
||||||
if (score < 0) // Never send messages to score below 0
|
|
||||||
sender.sendMessage("§cYou don't have permission to send this message or something went wrong");
|
|
||||||
else {
|
|
||||||
PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console,
|
|
||||||
String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID,
|
|
||||||
score, jsonstr));
|
|
||||||
val tc = ComponentManager.getIfEnabled(TownyComponent.class);
|
|
||||||
if (tc != null) tc.handleSpies(channel, json, ChatProcessing::toJson);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console,
|
|
||||||
String.format("tellraw @a %s", jsonstr));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex);
|
|
||||||
sender.sendMessage("§cAn error occured while sending the message.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
PluginMain.Instance.getServer().getConsoleSender()
|
|
||||||
.sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message));
|
|
||||||
DebugCommand.SendDebugMessage(
|
|
||||||
"-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms");
|
|
||||||
DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static String toJson(TellrawPart json) {
|
|
||||||
return gson.toJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player,
|
|
||||||
@Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier,
|
|
||||||
String origin) {
|
|
||||||
TellrawPart json = new TellrawPart("");
|
|
||||||
ChatOnlyComponent.tellrawCreate(mp, json); //TODO: Make nice API
|
|
||||||
json.addExtra(
|
|
||||||
new TellrawPart(channelidentifier)
|
|
||||||
.setHoverEvent(
|
|
||||||
TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
|
|
||||||
new TellrawPart((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 ("[" + (MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName().get())
|
|
||||||
+ "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
static ArrayList<ChatFormatter> addFormatters(Color colormode) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
ArrayList<ChatFormatter> formatters = (ArrayList<ChatFormatter>) commonFormatters.clone();
|
|
||||||
|
|
||||||
formatters.add(
|
|
||||||
ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
|
|
||||||
|
|
||||||
boolean nottest; //Not assigning a default value, so that it can only be used in the if
|
|
||||||
if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) {
|
|
||||||
StringBuilder namesb = new StringBuilder("(?i)(");
|
|
||||||
if (nottest)
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers())
|
|
||||||
namesb.append(p.getName()).append("|");
|
|
||||||
else
|
|
||||||
for (String testPlayer : testPlayers)
|
|
||||||
namesb.append(testPlayer).append("|");
|
|
||||||
namesb.deleteCharAt(namesb.length() - 1);
|
|
||||||
namesb.append(")");
|
|
||||||
StringBuilder nicksb = new StringBuilder("(?i)(");
|
|
||||||
boolean addNickFormatter = false;
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
|
||||||
final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId());
|
|
||||||
if (nick != null) {
|
|
||||||
nicksb.append(nick).append("|");
|
|
||||||
addNickFormatter = true; //Add it even if there's only 1 player online (it was in the if)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nicksb.deleteCharAt(nicksb.length() - 1);
|
|
||||||
nicksb.append(")");
|
|
||||||
|
|
||||||
Consumer<String> error = message -> {
|
|
||||||
if (PluginMain.Instance != null)
|
|
||||||
PluginMain.Instance.getLogger().warning(message);
|
|
||||||
else
|
|
||||||
System.out.println(message);
|
|
||||||
};
|
|
||||||
|
|
||||||
formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).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.isPresent()) {
|
|
||||||
error.accept("Error: Can't find player " + match + " but was reported as online.");
|
|
||||||
return "§c" + match + "§r";
|
|
||||||
}
|
|
||||||
ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class);
|
|
||||||
if (nottest) {
|
|
||||||
playPingSound(p);
|
|
||||||
}
|
|
||||||
String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor()));
|
|
||||||
return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing
|
|
||||||
}).priority(Priority.High).type(ChatFormatter.Type.Excluder).build());
|
|
||||||
|
|
||||||
if (addNickFormatter)
|
|
||||||
formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).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()));
|
|
||||||
if (p == null) {
|
|
||||||
error.accept("Error: Can't find player nicknamed "
|
|
||||||
+ match.toLowerCase() + " but was reported as online.");
|
|
||||||
return "§c" + match + "§r";
|
|
||||||
}
|
|
||||||
playPingSound(p);
|
|
||||||
return PluginMain.essentials.getUser(p).getNickname();
|
|
||||||
}
|
|
||||||
error.accept("Player nicknamed " + match.toLowerCase()
|
|
||||||
+ " not found in nickname map but was reported as online.");
|
|
||||||
return "§c" + match + "§r";
|
|
||||||
}).priority(Priority.High).type(ChatFormatter.Type.Excluder).build());
|
|
||||||
}
|
|
||||||
return formatters;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void playPingSound(Player p) {
|
|
||||||
if (PluginMain.Instance.notificationSound().get().length() == 0)
|
|
||||||
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
|
|
||||||
else
|
|
||||||
p.playSound(p.getLocation(), PluginMain.Instance.notificationSound().get(), 1.0f,
|
|
||||||
PluginMain.Instance.notificationPitch().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
|
|
||||||
val fc=ComponentManager.getIfEnabled(FunComponent.class);
|
|
||||||
if(fc!=null) fc.onChat(sender, event, message);
|
|
||||||
}
|
|
||||||
}
|
|
59
src/main/java/buttondevteam/chat/ChatUtils.java
Normal file
59
src/main/java/buttondevteam/chat/ChatUtils.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package buttondevteam.chat;
|
||||||
|
|
||||||
|
import buttondevteam.lib.ChromaUtils;
|
||||||
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
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
|
||||||
|
|
||||||
|
private ChatUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a console command.
|
||||||
|
*
|
||||||
|
* @param command The command
|
||||||
|
* @param async Whether the caller is async
|
||||||
|
*/
|
||||||
|
public static void dispatchConsoleCommand(String command, boolean async) {
|
||||||
|
if (async)
|
||||||
|
Bukkit.getScheduler().runTask(PluginMain.Instance, () -> Bukkit.dispatchCommand(PluginMain.Console, command));
|
||||||
|
else
|
||||||
|
Bukkit.dispatchCommand(PluginMain.Console, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string between the start and end strings (exclusive).
|
||||||
|
*
|
||||||
|
* @param str The original string
|
||||||
|
* @param start The start string
|
||||||
|
* @param end The end string
|
||||||
|
* @return The result string
|
||||||
|
*/
|
||||||
|
public static Optional<String> coolSubstring(String str, String start, String end) {
|
||||||
|
int a = str.indexOf(start) + start.length();
|
||||||
|
int b = str.indexOf(end, a);
|
||||||
|
return a != -1 && b != -1 ? Optional.of(str.substring(a, b)) : Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, 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(p))
|
||||||
|
p.sendMessage(str);
|
||||||
|
Bukkit.getConsoleSender().sendMessage(str);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,10 +5,12 @@ import buttondevteam.chat.commands.SnapCommand;
|
||||||
import buttondevteam.chat.commands.ucmds.HelpCommand;
|
import buttondevteam.chat.commands.ucmds.HelpCommand;
|
||||||
import buttondevteam.chat.commands.ucmds.HistoryCommand;
|
import buttondevteam.chat.commands.ucmds.HistoryCommand;
|
||||||
import buttondevteam.chat.commands.ucmds.InfoCommand;
|
import buttondevteam.chat.commands.ucmds.InfoCommand;
|
||||||
|
import buttondevteam.chat.commands.ucmds.ReloadCommand;
|
||||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||||
import buttondevteam.chat.components.announce.AnnouncerComponent;
|
import buttondevteam.chat.components.announce.AnnouncerComponent;
|
||||||
import buttondevteam.chat.components.appendext.AppendTextComponent;
|
import buttondevteam.chat.components.appendext.AppendTextComponent;
|
||||||
import buttondevteam.chat.components.flair.FlairComponent;
|
import buttondevteam.chat.components.flair.FlairComponent;
|
||||||
|
import buttondevteam.chat.components.formatter.FormatterComponent;
|
||||||
import buttondevteam.chat.components.fun.FunComponent;
|
import buttondevteam.chat.components.fun.FunComponent;
|
||||||
import buttondevteam.chat.components.towncolors.TownColorComponent;
|
import buttondevteam.chat.components.towncolors.TownColorComponent;
|
||||||
import buttondevteam.chat.components.towny.TownyComponent;
|
import buttondevteam.chat.components.towny.TownyComponent;
|
||||||
|
@ -28,7 +30,6 @@ import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.scoreboard.Scoreboard;
|
|
||||||
|
|
||||||
public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15.
|
public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15.
|
||||||
// A user, which flair isn't obtainable:
|
// A user, which flair isn't obtainable:
|
||||||
|
@ -36,8 +37,6 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
|
||||||
public static PluginMain Instance;
|
public static PluginMain Instance;
|
||||||
public static ConsoleCommandSender Console;
|
public static ConsoleCommandSender Console;
|
||||||
|
|
||||||
public static Scoreboard SB;
|
|
||||||
|
|
||||||
public ConfigData<String> notificationSound() {
|
public ConfigData<String> notificationSound() {
|
||||||
return getIConfig().getData("notificationSound", "");
|
return getIConfig().getData("notificationSound", "");
|
||||||
}
|
}
|
||||||
|
@ -54,11 +53,8 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
|
||||||
|
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerJoinLeaveListener(), this);
|
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerJoinLeaveListener(), this);
|
||||||
MainPlugin.Instance.setChatHandlerEnabled(false); //Disable Core chat handler
|
|
||||||
Console = this.getServer().getConsoleSender();
|
Console = this.getServer().getConsoleSender();
|
||||||
|
|
||||||
SB = getServer().getScoreboardManager().getMainScoreboard(); // Main can be detected with @a[score_...]
|
|
||||||
|
|
||||||
if (Bukkit.getPluginManager().isPluginEnabled("Towny"))
|
if (Bukkit.getPluginManager().isPluginEnabled("Towny"))
|
||||||
Component.registerComponent(this, new TownyComponent());
|
Component.registerComponent(this, new TownyComponent());
|
||||||
|
|
||||||
|
@ -73,11 +69,13 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
|
||||||
Component.registerComponent(this, new AnnouncerComponent());
|
Component.registerComponent(this, new AnnouncerComponent());
|
||||||
Component.registerComponent(this, new FunComponent());
|
Component.registerComponent(this, new FunComponent());
|
||||||
Component.registerComponent(this, new AppendTextComponent());
|
Component.registerComponent(this, new AppendTextComponent());
|
||||||
|
Component.registerComponent(this, new FormatterComponent());
|
||||||
getCommand2MC().registerCommand(new DebugCommand());
|
getCommand2MC().registerCommand(new DebugCommand());
|
||||||
getCommand2MC().registerCommand(new HelpCommand());
|
getCommand2MC().registerCommand(new HelpCommand());
|
||||||
getCommand2MC().registerCommand(new HistoryCommand());
|
getCommand2MC().registerCommand(new HistoryCommand());
|
||||||
getCommand2MC().registerCommand(new InfoCommand());
|
getCommand2MC().registerCommand(new InfoCommand());
|
||||||
getCommand2MC().registerCommand(new MWikiCommand());
|
getCommand2MC().registerCommand(new MWikiCommand());
|
||||||
|
getCommand2MC().registerCommand(new ReloadCommand());
|
||||||
getCommand2MC().registerCommand(new SnapCommand());
|
getCommand2MC().registerCommand(new SnapCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,122 @@
|
||||||
package buttondevteam.chat;
|
package buttondevteam.chat;
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
import buttondevteam.core.MainPlugin;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCChatEvent;
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import net.minecraft.server.v1_12_R1.EntityHuman.EnumChatVisibility;
|
import lombok.val;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class VanillaUtils {
|
public class VanillaUtils {
|
||||||
public int getMCScoreIfChatOn(Player p, TBMCChatEvent e) {
|
public String getGroupIfChatOn(Player p, TBMCChatEvent e) {
|
||||||
if (!(p instanceof CraftPlayer) || ((CraftPlayer) p).getHandle().getChatFlags() == EnumChatVisibility.FULL) // Only send if client allows chat
|
try {
|
||||||
return e.getMCScore(p);
|
if (isChatOn(p)) // Only send if client allows chat
|
||||||
else
|
return e.getGroupID(p);
|
||||||
return -1;
|
else
|
||||||
|
return null;
|
||||||
|
} catch (NoClassDefFoundError ex) {
|
||||||
|
MainPlugin.Instance.getLogger().warning("Compatibility error, can't check if the chat is hidden by the player.");
|
||||||
|
return e.getGroupID(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Predicate<Player> isChatOn;
|
||||||
|
|
||||||
|
private boolean isChatOn(Player p) {
|
||||||
|
try {
|
||||||
|
if (isChatOn == null) {
|
||||||
|
val cl = p.getClass();
|
||||||
|
if (notCraftPlayer(cl)) return true; // p instanceof CraftPlayer
|
||||||
|
val hm = cl.getMethod("getHandle");
|
||||||
|
val handle = hm.invoke(p); //p.getHandle()
|
||||||
|
val vpcl = handle.getClass();
|
||||||
|
val gcfm = vpcl.getMethod("getChatFlags");
|
||||||
|
Class<?> encl;
|
||||||
|
try {
|
||||||
|
encl = Class.forName(handle.getClass().getPackage().getName() + ".EnumChatVisibility");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
encl = Class.forName(handle.getClass().getPackage().getName() + ".EntityHuman$EnumChatVisibility");
|
||||||
|
}
|
||||||
|
val ff = encl.getField("FULL");
|
||||||
|
val full = ff.get(null); // EnumChatVisibility.FULL
|
||||||
|
isChatOn = pl -> {
|
||||||
|
try {
|
||||||
|
if (notCraftPlayer(pl.getClass())) return true; //Need to check each time
|
||||||
|
val ph = hm.invoke(pl); //pl.getHandle()
|
||||||
|
val flags = gcfm.invoke(ph); //handle.getChatFlags()
|
||||||
|
return flags == full;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return isChatOn.test(p);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private String version;
|
||||||
|
|
||||||
|
public short getMCVersion() {
|
||||||
|
if (version != null) return version;
|
||||||
|
val v = ChatUtils.coolSubstring(Bukkit.getServer().getVersion().getClass().getPackage().getName(),
|
||||||
|
"org.bukkit.craftbukkit.v", "_R1").orElse("1_8").replace("_", "");
|
||||||
|
return Short.parseShort(v);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private BiPredicate<Player, String> tellRaw;
|
||||||
|
|
||||||
|
public boolean tellRaw(Player p, String json) {
|
||||||
|
try {
|
||||||
|
if (tellRaw == null) {
|
||||||
|
val pcl = p.getClass();
|
||||||
|
if (notCraftPlayer(pcl)) return false;
|
||||||
|
val hm = pcl.getMethod("getHandle");
|
||||||
|
val handle = hm.invoke(p);
|
||||||
|
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");
|
||||||
|
val encl = Class.forName(nms + ".Entity");
|
||||||
|
val ffdm = ccucl.getMethod("filterForDisplay", iclcl, chatcompcl, encl);*/
|
||||||
|
|
||||||
|
val cscl = Class.forName(chatcompcl.getName() + "$ChatSerializer");
|
||||||
|
val am = cscl.getMethod("a", String.class);
|
||||||
|
|
||||||
|
tellRaw = (pl, jsonStr) -> {
|
||||||
|
if (notCraftPlayer(pl.getClass())) return false;
|
||||||
|
try {
|
||||||
|
val hhandle = hm.invoke(pl);
|
||||||
|
val deserialized = am.invoke(null, jsonStr);
|
||||||
|
//val filtered = ffdm.invoke(null, hhandle, deserialized, hhandle);
|
||||||
|
sendmsg.invoke(hhandle, deserialized);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*((CraftPlayer) p).getHandle().sendMessage(ChatComponentUtils
|
||||||
|
.filterForDisplay(((CraftPlayer) p).getHandle(),
|
||||||
|
IChatBaseComponent.ChatSerializer.a(json), ((CraftPlayer) p).getHandle()));*/
|
||||||
|
return tellRaw.test(p, json);
|
||||||
|
} catch (Exception e) {
|
||||||
|
PluginMain.Instance.getLogger().warning("Could not use tellRaw: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean notCraftPlayer(Class<?> cl) {
|
||||||
|
return !cl.getSimpleName().contains("CraftPlayer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public final class HelpCommand extends UCommandBase {
|
||||||
public boolean def(CommandSender sender, @Command2.TextArg @Command2.OptionalArg String topicOrCommand) {
|
public boolean def(CommandSender sender, @Command2.TextArg @Command2.OptionalArg String topicOrCommand) {
|
||||||
if (topicOrCommand == null) {
|
if (topicOrCommand == null) {
|
||||||
sender.sendMessage(new String[]{
|
sender.sendMessage(new String[]{
|
||||||
"§6---- Thorpe Help ----",
|
"§6---- Chroma Help ----",
|
||||||
"Do /u help <topic> for more info",
|
"Do /u help <topic> for more info",
|
||||||
"Do /u help <commandname> [subcommands] for more info about a command",
|
"Do /u help <commandname> [subcommands] for more info about a command",
|
||||||
"Topics:",
|
"Topics:",
|
||||||
|
|
|
@ -5,7 +5,6 @@ import buttondevteam.lib.chat.ChatMessage;
|
||||||
import buttondevteam.lib.chat.Command2;
|
import buttondevteam.lib.chat.Command2;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.experimental.var;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package buttondevteam.chat.commands.ucmds;
|
||||||
|
|
||||||
|
import buttondevteam.chat.PluginMain;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
@CommandClass(helpText = {
|
||||||
|
"Reload",
|
||||||
|
"Reloads the config"
|
||||||
|
}, modOnly = true)
|
||||||
|
public class ReloadCommand extends UCommandBase {
|
||||||
|
@Command2.Subcommand
|
||||||
|
public void def(CommandSender sender) {
|
||||||
|
if (PluginMain.Instance.tryReloadConfig())
|
||||||
|
sender.sendMessage("§bReloaded config");
|
||||||
|
else
|
||||||
|
sender.sendMessage("§cFailed to reload config.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ public class AnnounceCommand extends UCommandBase {
|
||||||
})
|
})
|
||||||
public boolean add(CommandSender sender, @Command2.TextArg String text) {
|
public boolean add(CommandSender sender, @Command2.TextArg String text) {
|
||||||
String finalmessage = text.replace('&', '§');
|
String finalmessage = text.replace('&', '§');
|
||||||
component.AnnounceMessages().get().add(finalmessage);
|
component.announceMessages().get().add(finalmessage);
|
||||||
sender.sendMessage("§bAnnouncement added.§r");
|
sender.sendMessage("§bAnnouncement added.§r");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,9 @@ public class AnnounceCommand extends UCommandBase {
|
||||||
String finalmessage1 = text.replace('&', '§');
|
String finalmessage1 = text.replace('&', '§');
|
||||||
if (index > 100)
|
if (index > 100)
|
||||||
return false;
|
return false;
|
||||||
while (component.AnnounceMessages().get().size() <= index)
|
while (component.announceMessages().get().size() <= index)
|
||||||
component.AnnounceMessages().get().add("");
|
component.announceMessages().get().add("");
|
||||||
component.AnnounceMessages().get().set(index, finalmessage1);
|
component.announceMessages().get().set(index, finalmessage1);
|
||||||
sender.sendMessage("Announcement edited.");
|
sender.sendMessage("Announcement edited.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,10 @@ public class AnnounceCommand extends UCommandBase {
|
||||||
sender.sendMessage("§bList of announce messages:§r");
|
sender.sendMessage("§bList of announce messages:§r");
|
||||||
sender.sendMessage("§bFormat: [index] message§r");
|
sender.sendMessage("§bFormat: [index] message§r");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String message : component.AnnounceMessages().get())
|
for (String message : component.announceMessages().get())
|
||||||
sender.sendMessage("[" + i++ + "] " + message);
|
sender.sendMessage("[" + i++ + "] " + message);
|
||||||
sender.sendMessage("§bCurrent wait time between announcements: "
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class AnnounceCommand extends UCommandBase {
|
||||||
"This command removes an announcement"
|
"This command removes an announcement"
|
||||||
})
|
})
|
||||||
public boolean remove(CommandSender sender, int index) {
|
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;
|
if (index < 0 || index > msgs.size()) return false;
|
||||||
msgs.remove(index);
|
msgs.remove(index);
|
||||||
sender.sendMessage("Announcement removed.");
|
sender.sendMessage("Announcement removed.");
|
||||||
|
@ -73,7 +73,7 @@ public class AnnounceCommand extends UCommandBase {
|
||||||
"This command sets the time between the announcements"
|
"This command sets the time between the announcements"
|
||||||
})
|
})
|
||||||
public boolean settime(CommandSender sender, int minutes) {
|
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");
|
sender.sendMessage("Time set between announce messages to " + minutes + " minutes");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,11 @@ import org.bukkit.Bukkit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class AnnouncerComponent extends Component<PluginMain> implements Runnable {
|
public class AnnouncerComponent extends Component<PluginMain> implements Runnable {
|
||||||
public ConfigData<ArrayList<String>> AnnounceMessages() {
|
public ConfigData<ArrayList<String>> announceMessages() {
|
||||||
return getConfig().getData("announceMessages", new ArrayList<>(0));
|
return getConfig().getData("announceMessages", new ArrayList<>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigData<Integer> AnnounceTime() {
|
public ConfigData<Integer> announceTime() {
|
||||||
return getConfig().getData("announceTime", 15 * 60 * 1000);
|
return getConfig().getData("announceTime", 15 * 60 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,15 +27,15 @@ public class AnnouncerComponent extends Component<PluginMain> implements Runnabl
|
||||||
public void run() {
|
public void run() {
|
||||||
while (isEnabled()) {
|
while (isEnabled()) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(AnnounceTime().get());
|
Thread.sleep(announceTime().get());
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on
|
if (Bukkit.getOnlinePlayers().size() == 0) continue; //Don't post to Discord if nobody is on
|
||||||
if (AnnounceMessages().get().size() > AnnounceMessageIndex) {
|
if (announceMessages().get().size() > AnnounceMessageIndex) {
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, AnnounceMessages().get().get(AnnounceMessageIndex), target);
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, announceMessages().get().get(AnnounceMessageIndex), target);
|
||||||
AnnounceMessageIndex++;
|
AnnounceMessageIndex++;
|
||||||
if (AnnounceMessageIndex == AnnounceMessages().get().size())
|
if (AnnounceMessageIndex == announceMessages().get().size())
|
||||||
AnnounceMessageIndex = 0;
|
AnnounceMessageIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package buttondevteam.chat.components.chatonly;
|
package buttondevteam.chat.components.chatonly;
|
||||||
|
|
||||||
import buttondevteam.chat.ChatPlayer;
|
import buttondevteam.chat.ChatPlayer;
|
||||||
import buttondevteam.chat.formatting.TellrawEvent;
|
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
|
||||||
import buttondevteam.chat.formatting.TellrawPart;
|
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class AcceptCommand extends UCommandBase {
|
||||||
}
|
}
|
||||||
if (p.FlairState().get().equals(FlairStates.NoComment) || p.UserNames().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("§cError: You need to write your username to the reddit thread§r");
|
||||||
player.sendMessage(component.FlairThreadURL().get());
|
player.sendMessage(component.flairThreadURL().get());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (username != null && !p.UserNames().contains(username)) {
|
if (username != null && !p.UserNames().contains(username)) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class FlairComponent extends Component<PluginMain> {
|
public class FlairComponent extends Component<PluginMain> {
|
||||||
ConfigData<String> FlairThreadURL() {
|
ConfigData<String> flairThreadURL() {
|
||||||
return getConfig().getData("flairThreadURL", "https://www.reddit.com/r/Chromagamers/comments/51ys94/flair_thread_for_the_mc_server/");
|
return getConfig().getData("flairThreadURL", "https://www.reddit.com/r/Chromagamers/comments/51ys94/flair_thread_for_the_mc_server/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public class FlairComponent extends Component<PluginMain> {
|
||||||
int errorcount = 0;
|
int errorcount = 0;
|
||||||
while (isEnabled()) {
|
while (isEnabled()) {
|
||||||
try {
|
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")
|
JsonArray json = new JsonParser().parse(body).getAsJsonArray().get(1).getAsJsonObject().get("data")
|
||||||
.getAsJsonObject().get("children").getAsJsonArray();
|
.getAsJsonObject().get("children").getAsJsonArray();
|
||||||
for (Object obj : json) {
|
for (Object obj : json) {
|
||||||
|
|
|
@ -0,0 +1,348 @@
|
||||||
|
package buttondevteam.chat.components.formatter;
|
||||||
|
|
||||||
|
import buttondevteam.chat.ChatPlayer;
|
||||||
|
import buttondevteam.chat.ChatUtils;
|
||||||
|
import buttondevteam.chat.PluginMain;
|
||||||
|
import buttondevteam.chat.VanillaUtils;
|
||||||
|
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||||
|
import buttondevteam.chat.components.chatonly.ChatOnlyComponent;
|
||||||
|
import buttondevteam.chat.components.formatter.formatting.ChatFormatter;
|
||||||
|
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
|
||||||
|
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
|
||||||
|
import buttondevteam.chat.components.formatter.formatting.TellrawSerializer;
|
||||||
|
import buttondevteam.chat.components.fun.FunComponent;
|
||||||
|
import buttondevteam.chat.components.towny.TownyComponent;
|
||||||
|
import buttondevteam.chat.listener.PlayerListener;
|
||||||
|
import buttondevteam.core.ComponentManager;
|
||||||
|
import buttondevteam.core.component.channel.Channel;
|
||||||
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
|
import buttondevteam.lib.TBMCChatEventBase;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.chat.Color;
|
||||||
|
import buttondevteam.lib.chat.Priority;
|
||||||
|
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.Lists;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import lombok.val;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ChatProcessing {
|
||||||
|
private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null");
|
||||||
|
private static final Pattern CYAN_PATTERN = Pattern.compile("cyan");
|
||||||
|
private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\");
|
||||||
|
private static final Pattern CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console"));
|
||||||
|
private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)");
|
||||||
|
private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),&]+(?:#[\\w]+)?)");
|
||||||
|
public static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+");
|
||||||
|
private static final Pattern UNDERLINED_PATTERN = Pattern.compile("_");
|
||||||
|
private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*");
|
||||||
|
private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*");
|
||||||
|
private static final Pattern CODE_PATTERN = Pattern.compile("`");
|
||||||
|
private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]]+)]\\(([^()]+)\\)");
|
||||||
|
private static final Pattern SOMEONE_PATTERN = Pattern.compile("@someone"); //TODO
|
||||||
|
private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~");
|
||||||
|
private static final Pattern SPOILER_PATTERN = Pattern.compile("\\|\\|");
|
||||||
|
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 boolean pingedconsole = false;
|
||||||
|
|
||||||
|
public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder("escape", ESCAPE_PATTERN).build();
|
||||||
|
|
||||||
|
private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList(
|
||||||
|
ChatFormatter.builder("bold", BOLD_PATTERN).bold(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
||||||
|
.priority(Priority.High).build(),
|
||||||
|
ChatFormatter.builder("italic", ITALIC_PATTERN).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(),
|
||||||
|
ChatFormatter.builder("underlined", UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
|
||||||
|
.build(),
|
||||||
|
ChatFormatter.builder("strikethrough", STRIKETHROUGH_PATTERN).strikethrough(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
||||||
|
.build(),
|
||||||
|
ChatFormatter.builder("spoiler", SPOILER_PATTERN).obfuscated(true).removeCharCount((short) 2).type(ChatFormatter.Type.Range)
|
||||||
|
.onmatch((match, cf, fs) -> {
|
||||||
|
cf.setHoverText(match);
|
||||||
|
return match;
|
||||||
|
}).build(),
|
||||||
|
ESCAPE_FORMATTER, ChatFormatter.builder("nullMention", NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
|
||||||
|
ChatFormatter.builder("consolePing", CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder, section) -> {
|
||||||
|
if (!pingedconsole) {
|
||||||
|
System.out.print("\007");
|
||||||
|
pingedconsole = true; // Will set it to false in ProcessChat
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
}).priority(Priority.High).build(),
|
||||||
|
|
||||||
|
ChatFormatter.builder("hashtag", HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1")
|
||||||
|
.priority(Priority.High).build(),
|
||||||
|
ChatFormatter.builder("cyan", CYAN_PATTERN).color(Color.Aqua).build(), // #55
|
||||||
|
ChatFormatter.builder("code", CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).type(ChatFormatter.Type.Range)
|
||||||
|
.build(),
|
||||||
|
ChatFormatter.builder("maskedLink", MASKED_LINK_PATTERN).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 "";
|
||||||
|
builder.setOpenlink(link);
|
||||||
|
return text;
|
||||||
|
}).type(ChatFormatter.Type.Excluder).build(),
|
||||||
|
ChatFormatter.builder("url", URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build());
|
||||||
|
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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean ProcessChat(TBMCChatEvent e, FormatterComponent component) {
|
||||||
|
Channel channel = e.getChannel();
|
||||||
|
CommandSender sender = e.getSender();
|
||||||
|
String message = e.getMessage();
|
||||||
|
long processstart = System.nanoTime();
|
||||||
|
Player player = (sender instanceof Player ? (Player) sender : null);
|
||||||
|
User user = PluginMain.essentials.getUser(player);
|
||||||
|
|
||||||
|
if (player != null) {
|
||||||
|
user.updateActivity(true); //Could talk in a private channel, so broadcast
|
||||||
|
if (user.isMuted())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
doFunStuff(sender, e, message);
|
||||||
|
|
||||||
|
final String channelidentifier = getChannelID(channel, e.getOrigin());
|
||||||
|
PluginMain.Instance.getServer().getConsoleSender()
|
||||||
|
.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)
|
||||||
|
|
||||||
|
ChatPlayer mp;
|
||||||
|
if (player != null)
|
||||||
|
mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class);
|
||||||
|
else //Due to the online player map, getPlayer() can be more efficient than getAs()
|
||||||
|
mp = e.getUser().getAs(ChatPlayer.class); //May be null
|
||||||
|
|
||||||
|
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<ChatFormatter> formatters;
|
||||||
|
if (component.allowFormatting().get()) {
|
||||||
|
formatters = addFormatters(colormode, e::shouldSendTo);
|
||||||
|
if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
|
||||||
|
final AtomicInteger rpc = new AtomicInteger(0);
|
||||||
|
formatters.add(ChatFormatter.builder("word", WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> {
|
||||||
|
cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
|
||||||
|
return match;
|
||||||
|
}).build());
|
||||||
|
}
|
||||||
|
pingedconsole = false; // Will set it to true onmatch (static constructor)
|
||||||
|
} else
|
||||||
|
formatters = Lists.newArrayList(ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN)
|
||||||
|
.color(Color.White).priority(Priority.Low).build()); //This formatter is necessary
|
||||||
|
|
||||||
|
TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin());
|
||||||
|
long combinetime = System.nanoTime();
|
||||||
|
ChatFormatter.Combine(formatters, message, json, component.getConfig());
|
||||||
|
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(sender);
|
||||||
|
if (senderGroup == null) { // Never send messages if the group is null
|
||||||
|
sender.sendMessage("§cYou don't have permission to send this message or something went wrong");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
val tc = ComponentManager.getIfEnabled(TownyComponent.class);
|
||||||
|
if (tc != null) tc.handleSpiesInit(channel, json, ChatProcessing::toJson);
|
||||||
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
|
final String group;
|
||||||
|
if (player != null
|
||||||
|
&& PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player)))
|
||||||
|
group = null; // Don't send the message to them
|
||||||
|
else
|
||||||
|
group = VanillaUtils.getGroupIfChatOn(p, e);
|
||||||
|
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())
|
||||||
|
VanillaUtils.tellRaw(p, jsonstr);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex);
|
||||||
|
sender.sendMessage("§cAn error occured while sending the message.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
DebugCommand.SendDebugMessage(
|
||||||
|
"-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms");
|
||||||
|
DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String toJson(TellrawPart json) {
|
||||||
|
return gson.toJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TellrawPart createTellraw(CommandSender sender, String message, @Nullable Player player,
|
||||||
|
@Nullable ChatPlayer mp, @Nullable ChromaGamerBase cg, final String channelidentifier,
|
||||||
|
String origin) {
|
||||||
|
TellrawPart json = new TellrawPart("");
|
||||||
|
ChatOnlyComponent.tellrawCreate(mp, json); //TODO: Make nice API
|
||||||
|
json.addExtra(
|
||||||
|
new TellrawPart(channelidentifier)
|
||||||
|
.setHoverEvent(
|
||||||
|
TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
|
||||||
|
new TellrawPart((ChatUtils.MCORIGIN.equals(origin) ? "" : "From " + origin + "n")
|
||||||
|
+ "Copy message").setColor(Color.Blue)))
|
||||||
|
.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message)));
|
||||||
|
if (PluginMain.permission.has(sender, "tbmc.badge.diamond"))
|
||||||
|
json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true)
|
||||||
|
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter")));
|
||||||
|
else if (PluginMain.permission.has(sender, "tbmc.badge.gold"))
|
||||||
|
json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true)
|
||||||
|
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter")));
|
||||||
|
json.addExtra(new TellrawPart(" <"));
|
||||||
|
TellrawPart hovertp = new TellrawPart("");
|
||||||
|
if (cg != null)
|
||||||
|
hovertp.addExtra(new TellrawPart(cg.getInfo(ChromaGamerBase.InfoTarget.MCHover)));
|
||||||
|
json.addExtra(new TellrawPart(getSenderName(sender, player))
|
||||||
|
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp)));
|
||||||
|
json.addExtra(new TellrawPart("> "));
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getSenderName(CommandSender sender, Player player) {
|
||||||
|
if (player == null)
|
||||||
|
return sender.getName();
|
||||||
|
return player.getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getChannelID(Channel channel, String origin) {
|
||||||
|
return ("[" + (ChatUtils.MCORIGIN.equals(origin) ? "" : "§8" + origin.substring(0, 1) + "§r|") + channel.DisplayName().get())
|
||||||
|
+ "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
static ArrayList<ChatFormatter> addFormatters(Color colormode, Predicate<Player> canSee) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
ArrayList<ChatFormatter> formatters = (ArrayList<ChatFormatter>) commonFormatters.clone();
|
||||||
|
|
||||||
|
formatters.add(
|
||||||
|
ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
|
||||||
|
|
||||||
|
boolean nottest; //Not assigning a default value, so that it can only be used in the if
|
||||||
|
if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || Bukkit.getVersion().equals("test")) {
|
||||||
|
StringBuilder namesb = new StringBuilder("(?i)(");
|
||||||
|
boolean addNameFormatter = false; //Needed because some names may be filtered out if they can't see the channel
|
||||||
|
if (nottest)
|
||||||
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (canSee.test(p)) {
|
||||||
|
namesb.append(p.getName()).append("|");
|
||||||
|
addNameFormatter = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (String testPlayer : testPlayers)
|
||||||
|
namesb.append(testPlayer).append("|");
|
||||||
|
addNameFormatter = true;
|
||||||
|
}
|
||||||
|
namesb.deleteCharAt(namesb.length() - 1);
|
||||||
|
namesb.append(")");
|
||||||
|
StringBuilder nicksb = new StringBuilder("(?i)(");
|
||||||
|
boolean addNickFormatter = false;
|
||||||
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (!canSee.test(p)) continue;
|
||||||
|
final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId());
|
||||||
|
if (nick != null) {
|
||||||
|
nicksb.append(nick).append("|");
|
||||||
|
addNickFormatter = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nicksb.deleteCharAt(nicksb.length() - 1);
|
||||||
|
nicksb.append(")");
|
||||||
|
|
||||||
|
Consumer<String> error = message -> {
|
||||||
|
if (PluginMain.Instance != null)
|
||||||
|
PluginMain.Instance.getLogger().warning(message);
|
||||||
|
else
|
||||||
|
System.out.println(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (addNameFormatter)
|
||||||
|
formatters.add(ChatFormatter.builder("name", Pattern.compile(namesb.toString())).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.isPresent()) {
|
||||||
|
error.accept("Error: Can't find player " + match + " but was reported as online.");
|
||||||
|
return "§c" + match + "§r";
|
||||||
|
}
|
||||||
|
ChatPlayer mpp = TBMCPlayer.getPlayer(nottest ? p.getUniqueId() : new UUID(0, 0), ChatPlayer.class);
|
||||||
|
if (nottest) {
|
||||||
|
playPingSound(p);
|
||||||
|
}
|
||||||
|
String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor()));
|
||||||
|
return color + (nottest ? p.getName() : pn.get()) + "§r"; //Fix name casing, except when testing
|
||||||
|
}).priority(Priority.High).type(ChatFormatter.Type.Excluder).build());
|
||||||
|
|
||||||
|
if (addNickFormatter)
|
||||||
|
formatters.add(ChatFormatter.builder("nickname", Pattern.compile(nicksb.toString())).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()));
|
||||||
|
if (p == null) {
|
||||||
|
error.accept("Error: Can't find player nicknamed "
|
||||||
|
+ match.toLowerCase() + " but was reported as online.");
|
||||||
|
return "§c" + match + "§r";
|
||||||
|
}
|
||||||
|
playPingSound(p);
|
||||||
|
return PluginMain.essentials.getUser(p).getNickname();
|
||||||
|
}
|
||||||
|
error.accept("Player nicknamed " + match.toLowerCase()
|
||||||
|
+ " not found in nickname map but was reported as online.");
|
||||||
|
return "§c" + match + "§r";
|
||||||
|
}).priority(Priority.High).type(ChatFormatter.Type.Excluder).build());
|
||||||
|
}
|
||||||
|
return formatters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void playPingSound(Player p) {
|
||||||
|
if (PluginMain.Instance.notificationSound().get().length() == 0)
|
||||||
|
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
|
||||||
|
else
|
||||||
|
p.playSound(p.getLocation(), PluginMain.Instance.notificationSound().get(), 1.0f,
|
||||||
|
PluginMain.Instance.notificationPitch().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
|
||||||
|
val fc = ComponentManager.getIfEnabled(FunComponent.class);
|
||||||
|
if (fc != null) fc.onChat(sender, event, message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package buttondevteam.chat.components.formatter;
|
||||||
|
|
||||||
|
import buttondevteam.chat.PluginMain;
|
||||||
|
import buttondevteam.core.ComponentManager;
|
||||||
|
import buttondevteam.core.MainPlugin;
|
||||||
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component handles the custom processing of chat messages. If this component is disabled channels won't be supported either in Minecraft.
|
||||||
|
* If you only want to disable the formatting features, set allowFormatting to false.
|
||||||
|
*/
|
||||||
|
public class FormatterComponent extends Component<PluginMain> {
|
||||||
|
ConfigData<Boolean> allowFormatting() {
|
||||||
|
return getConfig().getData("allowFormatting", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void enable() {
|
||||||
|
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.Instance.setChatHandlerEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the chat if the component is enabled.
|
||||||
|
*
|
||||||
|
* @param event The chat event
|
||||||
|
* @return Whether the chat message shouldn't be sent for some reason
|
||||||
|
*/
|
||||||
|
public static boolean handleChat(TBMCChatEvent event) {
|
||||||
|
FormatterComponent component = ComponentManager.getIfEnabled(FormatterComponent.class);
|
||||||
|
if (component == null) return false;
|
||||||
|
return ChatProcessing.ProcessChat(event, component);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
package buttondevteam.chat.formatting;
|
package buttondevteam.chat.components.formatter.formatting;
|
||||||
|
|
||||||
import buttondevteam.chat.ChatProcessing;
|
|
||||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||||
|
import buttondevteam.chat.components.formatter.ChatProcessing;
|
||||||
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
|
import buttondevteam.lib.architecture.IHaveConfig;
|
||||||
import buttondevteam.lib.chat.Color;
|
import buttondevteam.lib.chat.Color;
|
||||||
import buttondevteam.lib.chat.Priority;
|
import buttondevteam.lib.chat.Priority;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
@ -15,13 +17,13 @@ import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart)} is used to turn it into a {@link TellrawPart}, combining
|
* A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart, IHaveConfig)} 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
|
* 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.
|
* again.
|
||||||
*
|
|
||||||
* @author NorbiPeti
|
|
||||||
*
|
*
|
||||||
|
* @author NorbiPeti
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("UnusedAssignment")
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
public final class ChatFormatter {
|
public final class ChatFormatter {
|
||||||
|
@ -39,118 +41,120 @@ public final class ChatFormatter {
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
short removeCharCount = 0;
|
short removeCharCount = 0;
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
Type type = Type.Normal;
|
Type type = Type.Normal;
|
||||||
String hoverText;
|
String hoverText;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
public static ChatFormatterBuilder builder(String name, Pattern regex) {
|
||||||
|
return builder().regex(regex).name(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ChatFormatterBuilder builder() {
|
||||||
|
return new ChatFormatterBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigData<Boolean> enabled(IHaveConfig config) {
|
||||||
|
return config.getData(name + ".enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
Normal,
|
Normal,
|
||||||
/**
|
/**
|
||||||
* Matches a start and an end section which gets converted to one section (for example see italics)
|
* Matches a start and an end section which gets converted to one section (for example see italics)
|
||||||
*/
|
*/
|
||||||
Range,
|
Range,
|
||||||
/**
|
/**
|
||||||
* Exclude matching area from further processing (besides this formatter)
|
* Exclude matching area from further processing (besides this formatter)
|
||||||
*/
|
*/
|
||||||
Excluder
|
Excluder
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface TriFunc<T1, T2, T3, R> {
|
public interface TriFunc<T1, T2, T3, R> {
|
||||||
R apply(T1 x1, T2 x2, T3 x3);
|
R apply(T1 x1, T2 x2, T3 x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp) {
|
public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp, IHaveConfig config) {
|
||||||
/*
|
/*
|
||||||
* This method assumes that there is always a global formatter
|
* This method assumes that there is always a global formatter
|
||||||
*/
|
*/
|
||||||
header("ChatFormatter.Combine begin");
|
header("ChatFormatter.Combine begin");
|
||||||
ArrayList<FormattedSection> sections = new ArrayList<FormattedSection>();
|
ArrayList<FormattedSection> sections = new ArrayList<>();
|
||||||
|
|
||||||
for (ChatFormatter formatter : formatters) {
|
if (config != null) //null if testing
|
||||||
if (formatter.type != Type.Excluder)
|
formatters.removeIf(cf -> !cf.enabled(config).get()); //Remove disabled formatters
|
||||||
continue;
|
createSections(formatters, str, sections, true);
|
||||||
Matcher matcher = formatter.regex.matcher(str);
|
|
||||||
while (matcher.find()) {
|
|
||||||
DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
|
|
||||||
DebugCommand.SendDebugMessage("With excluder formatter:" + formatter);
|
|
||||||
sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
|
|
||||||
if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
|
|
||||||
DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
|
|
||||||
continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
|
|
||||||
}
|
|
||||||
ArrayList<String> groups = new ArrayList<String>();
|
|
||||||
for (int i = 0; i < matcher.groupCount(); i++)
|
|
||||||
groups.add(matcher.group(i + 1));
|
|
||||||
if (groups.size() > 0)
|
|
||||||
DebugCommand.SendDebugMessage("First group: " + groups.get(0));
|
|
||||||
FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
|
|
||||||
formatter.type);
|
|
||||||
sections.add(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
header("Section creation (excluders done)");
|
header("Section creation (excluders done)");
|
||||||
for (ChatFormatter formatter : formatters) {
|
createSections(formatters, str, sections, false);
|
||||||
if (formatter.type == Type.Excluder)
|
sortSections(sections);
|
||||||
continue;
|
|
||||||
Matcher matcher = formatter.regex.matcher(str);
|
|
||||||
while (matcher.find()) {
|
|
||||||
DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
|
|
||||||
DebugCommand.SendDebugMessage("With formatter:" + formatter);
|
|
||||||
sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
|
|
||||||
if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
|
|
||||||
DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
|
|
||||||
continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
|
|
||||||
}
|
|
||||||
ArrayList<String> groups = new ArrayList<String>();
|
|
||||||
for (int i = 0; i < matcher.groupCount(); i++)
|
|
||||||
groups.add(matcher.group(i + 1));
|
|
||||||
if (groups.size() > 0)
|
|
||||||
DebugCommand.SendDebugMessage("First group: " + groups.get(0));
|
|
||||||
FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
|
|
||||||
formatter.type);
|
|
||||||
sections.add(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sections.sort(
|
|
||||||
(s1, s2) -> s1.Start == s2.Start
|
|
||||||
? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
|
|
||||||
s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End)
|
|
||||||
: Integer.compare(s1.Start, s2.Start));
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* 0: Start - 1: End index
|
* 0: Start - 1: End index
|
||||||
*/
|
*/
|
||||||
val remchars = new ArrayList<int[]>();
|
val remchars = new ArrayList<int[]>();
|
||||||
|
|
||||||
header("Range section conversion");
|
header("Range section conversion");
|
||||||
|
sections = convertRangeSections(str, sections, remchars);
|
||||||
|
|
||||||
|
header("Adding remove chars (RC)"); // Important to add after the range section conversion
|
||||||
|
addRemChars(sections, remchars);
|
||||||
|
|
||||||
|
header("Section combining");
|
||||||
|
combineSections(str, sections);
|
||||||
|
|
||||||
|
header("Section applying");
|
||||||
|
applySections(str, tp, sections, remchars);
|
||||||
|
header("ChatFormatter.Combine done");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createSections(List<ChatFormatter> formatters, String str, ArrayList<FormattedSection> sections,
|
||||||
|
boolean excluders) {
|
||||||
|
for (ChatFormatter formatter : formatters) {
|
||||||
|
if (excluders == (formatter.type != Type.Excluder))
|
||||||
|
continue; //If we're looking at excluders and this isn't one, skip - or vica-versa
|
||||||
|
Matcher matcher = formatter.regex.matcher(str);
|
||||||
|
while (matcher.find()) {
|
||||||
|
DebugCommand.SendDebugMessage("Found match from " + matcher.start() + " to " + (matcher.end() - 1));
|
||||||
|
DebugCommand.SendDebugMessage("With " + (excluders ? "excluder " : "") + "formatter: " + formatter);
|
||||||
|
sendMessageWithPointer(str, matcher.start(), matcher.end() - 1);
|
||||||
|
if (formatter.regex != ChatProcessing.ENTIRE_MESSAGE_PATTERN && sections.stream().anyMatch(fs -> fs.type == Type.Excluder && (fs.End >= matcher.start() && fs.Start <= matcher.end() - 1))) {
|
||||||
|
DebugCommand.SendDebugMessage("Ignoring formatter because of an excluder");
|
||||||
|
continue; //Exclude areas matched by excluders - Range sections are correctly handled afterwards
|
||||||
|
}
|
||||||
|
ArrayList<String> groups = new ArrayList<>();
|
||||||
|
for (int i = 0; i < matcher.groupCount(); i++)
|
||||||
|
groups.add(matcher.group(i + 1));
|
||||||
|
if (groups.size() > 0)
|
||||||
|
DebugCommand.SendDebugMessage("First group: " + groups.get(0));
|
||||||
|
FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
|
||||||
|
formatter.type);
|
||||||
|
sections.add(section);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArrayList<FormattedSection> convertRangeSections(String str, ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
|
||||||
ArrayList<FormattedSection> combined = new ArrayList<>();
|
ArrayList<FormattedSection> combined = new ArrayList<>();
|
||||||
Map<ChatFormatter, FormattedSection> nextSection = new HashMap<>();
|
Map<ChatFormatter, FormattedSection> nextSection = new HashMap<>();
|
||||||
boolean escaped = false;
|
boolean escaped = false;
|
||||||
int takenStart = -1, takenEnd = -1;
|
int takenStart = -1, takenEnd = -1;
|
||||||
ChatFormatter takenFormatter = null;
|
ChatFormatter takenFormatter = null;
|
||||||
for (int i = 0; i < sections.size(); i++) {
|
for (final FormattedSection section : sections) {
|
||||||
// Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true
|
// Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true
|
||||||
final FormattedSection section = sections.get(i);
|
if (section.type != Type.Range) {
|
||||||
if (section.type!=Type.Range) {
|
|
||||||
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
|
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
|
||||||
if (escaped) {// Don't add the escape character
|
if (escaped) {// Don't add the escape character
|
||||||
remchars.add(new int[]{section.Start, section.Start});
|
remchars.add(new int[]{section.Start, section.Start});
|
||||||
DebugCommand.SendDebugMessage("Found escaper section: " + section);
|
DebugCommand.SendDebugMessage("Found escaper section: " + section);
|
||||||
} else {
|
} else {
|
||||||
combined.add(section); // The above will delete the \
|
combined.add(section); // The above will delete the \
|
||||||
DebugCommand.SendDebugMessage("Added section: " + section);
|
DebugCommand.SendDebugMessage("Added section: " + section);
|
||||||
}
|
}
|
||||||
sendMessageWithPointer(str, section.Start, section.End);
|
sendMessageWithPointer(str, section.Start, section.End);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!escaped) {
|
if (!escaped) {
|
||||||
if (combined.stream().anyMatch(s -> section.type != Type.Range && (s.Start == section.Start
|
|
||||||
|| (s.Start < section.Start ? s.End >= section.Start : s.Start <= section.End)))) {
|
|
||||||
DebugCommand.SendDebugMessage("Range " + section + " overlaps with a combined section, ignoring.");
|
|
||||||
sendMessageWithPointer(str, section.Start, section.End);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (section.Start == takenStart || (section.Start > takenStart && section.Start < takenEnd)) {
|
if (section.Start == takenStart || (section.Start > takenStart && section.Start < takenEnd)) {
|
||||||
/*
|
/*
|
||||||
* if (nextSection.containsKey(section.Formatters.get(0)) ? section.RemCharFromStart <= takenEnd - takenStart : section.RemCharFromStart > takenEnd - takenStart) {
|
* if (nextSection.containsKey(section.Formatters.get(0)) ? section.RemCharFromStart <= takenEnd - takenStart : section.RemCharFromStart > takenEnd - takenStart) {
|
||||||
|
@ -183,7 +187,7 @@ public final class ChatFormatter {
|
||||||
nextSection.put(section.Formatters.get(0), section);
|
nextSection.put(section.Formatters.get(0), section);
|
||||||
}
|
}
|
||||||
DebugCommand
|
DebugCommand
|
||||||
.SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter);
|
.SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter);
|
||||||
sendMessageWithPointer(str, takenStart, takenEnd);
|
sendMessageWithPointer(str, takenStart, takenEnd);
|
||||||
} else {
|
} else {
|
||||||
DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character)
|
DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character)
|
||||||
|
@ -193,24 +197,27 @@ public final class ChatFormatter {
|
||||||
}
|
}
|
||||||
//Do not finish unfinished sections, ignore them
|
//Do not finish unfinished sections, ignore them
|
||||||
sections = combined;
|
sections = combined;
|
||||||
|
return sections;
|
||||||
|
}
|
||||||
|
|
||||||
header("Adding remove chars (RC)"); // Important to add after the range section conversion
|
private static void addRemChars(ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
|
||||||
sections.stream()
|
sections.stream()
|
||||||
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
|
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
|
||||||
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1}))
|
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1}))
|
||||||
.forEach(rc -> remchars.add(rc));
|
.forEach(remchars::add);
|
||||||
sections.stream()
|
sections.stream()
|
||||||
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
|
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
|
||||||
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End}))
|
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End}))
|
||||||
.forEach(rc -> remchars.add(rc));
|
.forEach(remchars::add);
|
||||||
DebugCommand.SendDebugMessage("Added remchars:");
|
DebugCommand.SendDebugMessage("Added remchars:");
|
||||||
DebugCommand
|
DebugCommand
|
||||||
.SendDebugMessage(remchars.stream().map(rc -> Arrays.toString(rc)).collect(Collectors.joining("; ")));
|
.SendDebugMessage(remchars.stream().map(Arrays::toString).collect(Collectors.joining("; ")));
|
||||||
|
}
|
||||||
|
|
||||||
header("Section combining");
|
private static void combineSections(String str, ArrayList<FormattedSection> sections) {
|
||||||
boolean cont = true;
|
boolean cont = true;
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (int i = 1; cont;) {
|
for (int i = 1; cont; ) {
|
||||||
int nextindex = i + 1;
|
int nextindex = i + 1;
|
||||||
if (sections.size() < 2)
|
if (sections.size() < 2)
|
||||||
break;
|
break;
|
||||||
|
@ -218,47 +225,40 @@ public final class ChatFormatter {
|
||||||
FormattedSection firstSection = sections.get(i - 1);
|
FormattedSection firstSection = sections.get(i - 1);
|
||||||
DebugCommand.SendDebugMessage("Combining sections " + firstSection);
|
DebugCommand.SendDebugMessage("Combining sections " + firstSection);
|
||||||
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||||
DebugCommand.SendDebugMessage(" and " + sections.get(i));
|
final FormattedSection lastSection = sections.get(i);
|
||||||
sendMessageWithPointer(str, sections.get(i).Start, sections.get(i).End);
|
DebugCommand.SendDebugMessage(" and " + lastSection);
|
||||||
if (firstSection.Start == sections.get(i).Start && firstSection.End == sections.get(i).End) {
|
sendMessageWithPointer(str, lastSection.Start, lastSection.End);
|
||||||
firstSection.Formatters.addAll(sections.get(i).Formatters);
|
if (firstSection.Start == lastSection.Start && firstSection.End == lastSection.End) {
|
||||||
firstSection.Matches.addAll(sections.get(i).Matches);
|
firstSection.Formatters.addAll(lastSection.Formatters);
|
||||||
|
firstSection.Matches.addAll(lastSection.Matches);
|
||||||
DebugCommand.SendDebugMessage("To section " + firstSection);
|
DebugCommand.SendDebugMessage("To section " + firstSection);
|
||||||
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||||
sections.remove(i);
|
sections.remove(i);
|
||||||
found = true;
|
found = true;
|
||||||
} else if (firstSection.End > sections.get(i).Start && firstSection.Start < sections.get(i).End) {
|
} else if (firstSection.End > lastSection.Start && firstSection.Start < lastSection.End) {
|
||||||
int origend = firstSection.End;
|
int origend2 = firstSection.End;
|
||||||
firstSection.End = sections.get(i).Start - 1;
|
firstSection.End = lastSection.Start - 1;
|
||||||
int origend2 = sections.get(i).End;
|
int origend = lastSection.End;
|
||||||
boolean switchends;
|
FormattedSection section = new FormattedSection(firstSection.Formatters, lastSection.Start, origend,
|
||||||
if (switchends = origend2 < origend) {
|
firstSection.Matches, Type.Normal);
|
||||||
int tmp = origend;
|
section.Formatters.addAll(lastSection.Formatters);
|
||||||
origend = origend2;
|
section.Matches.addAll(lastSection.Matches); // TODO: Clean
|
||||||
origend2 = tmp;
|
|
||||||
}
|
|
||||||
FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend,
|
|
||||||
firstSection.Matches, Type.Normal);
|
|
||||||
section.Formatters.addAll(sections.get(i).Formatters);
|
|
||||||
section.Matches.addAll(sections.get(i).Matches); // TODO: Clean
|
|
||||||
sections.add(i, section);
|
sections.add(i, section);
|
||||||
nextindex++;
|
nextindex++;
|
||||||
FormattedSection thirdFormattedSection = sections.get(i + 1);
|
// Use the properties of the first section not the second one
|
||||||
if (switchends) { // Use the properties of the first section not the second one
|
lastSection.Formatters.clear();
|
||||||
thirdFormattedSection.Formatters.clear();
|
lastSection.Formatters.addAll(firstSection.Formatters);
|
||||||
thirdFormattedSection.Formatters.addAll(firstSection.Formatters);
|
lastSection.Matches.clear();
|
||||||
thirdFormattedSection.Matches.clear();
|
lastSection.Matches.addAll(firstSection.Matches);
|
||||||
thirdFormattedSection.Matches.addAll(firstSection.Matches);
|
|
||||||
}
|
lastSection.Start = origend + 1;
|
||||||
thirdFormattedSection.Start = origend + 1;
|
lastSection.End = origend2;
|
||||||
thirdFormattedSection.End = origend2;
|
|
||||||
|
|
||||||
ArrayList<FormattedSection> sts = sections;
|
|
||||||
Predicate<FormattedSection> removeIfNeeded = s -> {
|
Predicate<FormattedSection> removeIfNeeded = s -> {
|
||||||
if (s.Start < 0 || s.End < 0 || s.Start > s.End) {
|
if (s.Start < 0 || s.End < 0 || s.Start > s.End) {
|
||||||
DebugCommand.SendDebugMessage("Removing section: " + s);
|
DebugCommand.SendDebugMessage("Removing section: " + s);
|
||||||
sendMessageWithPointer(str, s.Start, s.End);
|
sendMessageWithPointer(str, s.Start, s.End);
|
||||||
sts.remove(s);
|
sections.remove(s);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -273,9 +273,9 @@ public final class ChatFormatter {
|
||||||
DebugCommand.SendDebugMessage(" 2:" + section + "");
|
DebugCommand.SendDebugMessage(" 2:" + section + "");
|
||||||
sendMessageWithPointer(str, section.Start, section.End);
|
sendMessageWithPointer(str, section.Start, section.End);
|
||||||
}
|
}
|
||||||
if (!removeIfNeeded.test(thirdFormattedSection)) {
|
if (!removeIfNeeded.test(lastSection)) {
|
||||||
DebugCommand.SendDebugMessage(" 3:" + thirdFormattedSection);
|
DebugCommand.SendDebugMessage(" 3:" + lastSection);
|
||||||
sendMessageWithPointer(str, thirdFormattedSection.Start, thirdFormattedSection.End);
|
sendMessageWithPointer(str, lastSection.Start, lastSection.End);
|
||||||
}
|
}
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
@ -294,48 +294,44 @@ public final class ChatFormatter {
|
||||||
if (found) {
|
if (found) {
|
||||||
i = 1;
|
i = 1;
|
||||||
found = false;
|
found = false;
|
||||||
sections.sort(
|
sortSections(sections);
|
||||||
(s1, s2) -> s1.Start == s2.Start
|
|
||||||
? s1.End == s2.End
|
|
||||||
? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
|
|
||||||
s1.Formatters.get(0).priority.GetValue())
|
|
||||||
: Integer.compare(s2.End, s1.End)
|
|
||||||
: Integer.compare(s1.Start, s2.Start));
|
|
||||||
} else
|
} else
|
||||||
cont = false;
|
cont = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
header("Section applying");
|
private static void applySections(String str, TellrawPart tp, ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
|
||||||
TellrawPart lasttp = null; String lastlink = null;
|
TellrawPart lasttp = null;
|
||||||
for (FormattedSection section : sections) {
|
String lastlink = null;
|
||||||
|
for (FormattedSection section : sections) {
|
||||||
DebugCommand.SendDebugMessage("Applying section: " + section);
|
DebugCommand.SendDebugMessage("Applying section: " + section);
|
||||||
String originaltext;
|
String originaltext;
|
||||||
int start = section.Start, end = section.End;
|
int start = section.Start, end = section.End;
|
||||||
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
|
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
|
||||||
sendMessageWithPointer(str, start, end);
|
sendMessageWithPointer(str, start, end);
|
||||||
val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
|
val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
|
||||||
val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
|
val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
|
||||||
val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new);
|
val rci = remchars.stream().filter(rc -> start < rc[0] && rc[1] < end).toArray(int[][]::new);
|
||||||
int s = start, e = end;
|
int s = start, e = end;
|
||||||
if (rcs.isPresent())
|
if (rcs.isPresent())
|
||||||
s = rcs.get()[1] + 1;
|
s = rcs.get()[1] + 1;
|
||||||
if (rce.isPresent())
|
if (rce.isPresent())
|
||||||
e = rce.get()[0] - 1;
|
e = rce.get()[0] - 1;
|
||||||
DebugCommand.SendDebugMessage("After RC - Start: " + s + " - End: " + e);
|
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
|
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) + ")");
|
DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
originaltext = str.substring(s, e + 1);
|
originaltext = str.substring(s, e + 1);
|
||||||
val sb = new StringBuilder(originaltext);
|
val sb = new StringBuilder(originaltext);
|
||||||
for (int x = rci.length - 1; x >= 0; x--)
|
for (int x = rci.length - 1; x >= 0; x--)
|
||||||
sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards
|
sb.delete(rci[x][0] - start - 1, rci[x][1] - start); //Delete going backwards
|
||||||
originaltext = sb.toString();
|
originaltext = sb.toString();
|
||||||
DebugCommand.SendDebugMessage("Section text: " + originaltext);
|
DebugCommand.SendDebugMessage("Section text: " + originaltext);
|
||||||
String openlink = null;
|
String openlink = null;
|
||||||
section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
|
section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
|
||||||
TellrawPart newtp = new TellrawPart("");
|
TellrawPart newtp = new TellrawPart("");
|
||||||
for (ChatFormatter formatter : section.Formatters) {
|
for (ChatFormatter formatter : section.Formatters) {
|
||||||
DebugCommand.SendDebugMessage("Applying formatter: " + formatter);
|
DebugCommand.SendDebugMessage("Applying formatter: " + formatter);
|
||||||
if (formatter.onmatch != null)
|
if (formatter.onmatch != null)
|
||||||
|
@ -343,42 +339,50 @@ public final class ChatFormatter {
|
||||||
if (formatter.color != null)
|
if (formatter.color != null)
|
||||||
newtp.setColor(formatter.color);
|
newtp.setColor(formatter.color);
|
||||||
if (formatter.bold)
|
if (formatter.bold)
|
||||||
newtp.setBold(formatter.bold);
|
newtp.setBold(true);
|
||||||
if (formatter.italic)
|
if (formatter.italic)
|
||||||
newtp.setItalic(formatter.italic);
|
newtp.setItalic(true);
|
||||||
if (formatter.underlined)
|
if (formatter.underlined)
|
||||||
newtp.setUnderlined(formatter.underlined);
|
newtp.setUnderlined(true);
|
||||||
if (formatter.strikethrough)
|
if (formatter.strikethrough)
|
||||||
newtp.setStrikethrough(formatter.strikethrough);
|
newtp.setStrikethrough(true);
|
||||||
if (formatter.obfuscated)
|
if (formatter.obfuscated)
|
||||||
newtp.setObfuscated(formatter.obfuscated);
|
newtp.setObfuscated(true);
|
||||||
if (formatter.openlink != null)
|
if (formatter.openlink != null)
|
||||||
openlink = formatter.openlink;
|
openlink = formatter.openlink;
|
||||||
if (formatter.hoverText != null)
|
if (formatter.hoverText != null)
|
||||||
newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, formatter.hoverText));
|
newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, formatter.hoverText));
|
||||||
}
|
}
|
||||||
if (lasttp != null && newtp.getColor() == lasttp.getColor()
|
if (lasttp != null && newtp.getColor() == lasttp.getColor()
|
||||||
&& newtp.isBold() == lasttp.isBold()
|
&& newtp.isBold() == lasttp.isBold()
|
||||||
&& newtp.isItalic() == lasttp.isItalic()
|
&& newtp.isItalic() == lasttp.isItalic()
|
||||||
&& newtp.isUnderlined() == lasttp.isUnderlined()
|
&& newtp.isUnderlined() == lasttp.isUnderlined()
|
||||||
&& newtp.isStrikethrough() == lasttp.isStrikethrough()
|
&& newtp.isStrikethrough() == lasttp.isStrikethrough()
|
||||||
&& newtp.isObfuscated() == lasttp.isObfuscated()
|
&& newtp.isObfuscated() == lasttp.isObfuscated()
|
||||||
&& Objects.equals(openlink, lastlink)) {
|
&& Objects.equals(openlink, lastlink)) {
|
||||||
DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
|
DebugCommand.SendDebugMessage("This part has the same properties as the previous one, combining.");
|
||||||
lasttp.setText(lasttp.getText() + originaltext);
|
lasttp.setText(lasttp.getText() + originaltext);
|
||||||
continue; //Combine parts with the same properties
|
continue; //Combine parts with the same properties
|
||||||
}
|
}
|
||||||
|
lastlink = openlink;
|
||||||
newtp.setText(originaltext);
|
newtp.setText(originaltext);
|
||||||
if (openlink != null && openlink.length() > 0) {
|
if (openlink != null && openlink.length() > 0) {
|
||||||
newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL,
|
newtp.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.OPEN_URL,
|
||||||
(section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
|
(section.Matches.size() > 0 ? openlink.replace("$1", section.Matches.get(0)) : openlink)))
|
||||||
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
|
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
|
||||||
new TellrawPart("Click to open").setColor(Color.Blue)));
|
new TellrawPart("Click to open").setColor(Color.Blue)));
|
||||||
}
|
}
|
||||||
tp.addExtra(newtp);
|
tp.addExtra(newtp);
|
||||||
lasttp = newtp;
|
lasttp = newtp;
|
||||||
}
|
}
|
||||||
header("ChatFormatter.Combine done");
|
}
|
||||||
|
|
||||||
|
private static void sortSections(ArrayList<FormattedSection> sections) {
|
||||||
|
sections.sort(
|
||||||
|
(s1, s2) -> s1.Start == s2.Start
|
||||||
|
? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
|
||||||
|
s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End)
|
||||||
|
: Integer.compare(s1.Start, s2.Start));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendMessageWithPointer(String str, int... pointer) {
|
private static void sendMessageWithPointer(String str, int... pointer) {
|
|
@ -1,4 +1,4 @@
|
||||||
package buttondevteam.chat.formatting;
|
package buttondevteam.chat.components.formatter.formatting;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
|
@ -1,76 +1,76 @@
|
||||||
package buttondevteam.chat.formatting;
|
package buttondevteam.chat.components.formatter.formatting;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import buttondevteam.lib.chat.TellrawSerializableEnum;
|
||||||
|
|
||||||
import buttondevteam.lib.chat.TellrawSerializableEnum;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public final class TellrawEvent<T extends TellrawEvent.Action> implements Serializable {
|
public final class TellrawEvent<T extends TellrawEvent.Action> implements Serializable {
|
||||||
private static final long serialVersionUID = -1681364161210561505L;
|
private static final long serialVersionUID = -1681364161210561505L;
|
||||||
private transient boolean hoverEvent;
|
private transient boolean hoverEvent;
|
||||||
private T action;
|
private T action;
|
||||||
private Object value;
|
private Object value;
|
||||||
|
|
||||||
private TellrawEvent(T action, String value) {
|
private TellrawEvent(T action, String value) {
|
||||||
this.hoverEvent = action instanceof HoverAction;
|
this.hoverEvent = action instanceof HoverAction;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TellrawEvent(T action, TellrawPart value) {
|
private TellrawEvent(T action, TellrawPart value) {
|
||||||
this.hoverEvent = action instanceof HoverAction;
|
this.hoverEvent = action instanceof HoverAction;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V extends TellrawEvent.Action> TellrawEvent<V> create(V action, String value) {
|
public static <V extends TellrawEvent.Action> TellrawEvent<V> create(V action, String value) {
|
||||||
return new TellrawEvent<>(action, value);
|
return new TellrawEvent<>(action, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V extends TellrawEvent.Action> TellrawEvent<V> create(V action, TellrawPart value) {
|
public static <V extends TellrawEvent.Action> TellrawEvent<V> create(V action, TellrawPart value) {
|
||||||
return new TellrawEvent<>(action, value);
|
return new TellrawEvent<>(action, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHoverEvent() {
|
public boolean isHoverEvent() {
|
||||||
return hoverEvent;
|
return hoverEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getAction() {
|
public T getAction() {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ClickAction implements Action {
|
public enum ClickAction implements Action {
|
||||||
OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command");
|
OPEN_URL("open_url"), RUN_COMMAND("run_command"), SUGGEST_COMMAND("suggest_command");
|
||||||
private String action;
|
private String action;
|
||||||
|
|
||||||
ClickAction(String action) {
|
ClickAction(String action) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum HoverAction implements Action {
|
public enum HoverAction implements Action {
|
||||||
SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY(
|
SHOW_TEXT("show_text"), SHOW_ITEM("show_item"), SHOW_ACHIEVEMENT("show_achievement"), SHOW_ENTITY(
|
||||||
"show_entity");
|
"show_entity");
|
||||||
private String action;
|
private String action;
|
||||||
|
|
||||||
HoverAction(String action) {
|
HoverAction(String action) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface Action extends TellrawSerializableEnum {
|
public static interface Action extends TellrawSerializableEnum {
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,115 +1,115 @@
|
||||||
package buttondevteam.chat.formatting;
|
package buttondevteam.chat.components.formatter.formatting;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import buttondevteam.lib.chat.Color;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import buttondevteam.lib.chat.*;
|
import java.util.List;
|
||||||
|
|
||||||
public final class TellrawPart implements Serializable {
|
public final class TellrawPart implements Serializable {
|
||||||
private static final long serialVersionUID = 4125357644462144024L;
|
private static final long serialVersionUID = 4125357644462144024L;
|
||||||
private Color color;
|
private Color color;
|
||||||
private boolean italic;
|
private boolean italic;
|
||||||
private boolean bold;
|
private boolean bold;
|
||||||
private boolean underlined;
|
private boolean underlined;
|
||||||
private boolean strikethrough;
|
private boolean strikethrough;
|
||||||
private boolean obfuscated;
|
private boolean obfuscated;
|
||||||
private List<TellrawPart> extra = new ArrayList<>();
|
private List<TellrawPart> extra = new ArrayList<>();
|
||||||
private String text;
|
private String text;
|
||||||
private TellrawEvent<TellrawEvent.HoverAction> hoverEvent;
|
private TellrawEvent<TellrawEvent.HoverAction> hoverEvent;
|
||||||
private TellrawEvent<TellrawEvent.ClickAction> clickEvent;
|
private TellrawEvent<TellrawEvent.ClickAction> clickEvent;
|
||||||
|
|
||||||
public TellrawPart(String text) {
|
public TellrawPart(String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color getColor() {
|
public Color getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setColor(Color color) {
|
public TellrawPart setColor(Color color) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isItalic() {
|
public boolean isItalic() {
|
||||||
return italic;
|
return italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setItalic(boolean italic) {
|
public TellrawPart setItalic(boolean italic) {
|
||||||
this.italic = italic;
|
this.italic = italic;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBold() {
|
public boolean isBold() {
|
||||||
return bold;
|
return bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setBold(boolean bold) {
|
public TellrawPart setBold(boolean bold) {
|
||||||
this.bold = bold;
|
this.bold = bold;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnderlined() {
|
public boolean isUnderlined() {
|
||||||
return underlined;
|
return underlined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setUnderlined(boolean underlined) {
|
public TellrawPart setUnderlined(boolean underlined) {
|
||||||
this.underlined = underlined;
|
this.underlined = underlined;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStrikethrough() {
|
public boolean isStrikethrough() {
|
||||||
return strikethrough;
|
return strikethrough;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setStrikethrough(boolean strikethrough) {
|
public TellrawPart setStrikethrough(boolean strikethrough) {
|
||||||
this.strikethrough = strikethrough;
|
this.strikethrough = strikethrough;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isObfuscated() {
|
public boolean isObfuscated() {
|
||||||
return obfuscated;
|
return obfuscated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setObfuscated(boolean obfuscated) {
|
public TellrawPart setObfuscated(boolean obfuscated) {
|
||||||
this.obfuscated = obfuscated;
|
this.obfuscated = obfuscated;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<TellrawPart> getExtra() {
|
public Iterable<TellrawPart> getExtra() {
|
||||||
return extra;
|
return extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart addExtra(TellrawPart extra) {
|
public TellrawPart addExtra(TellrawPart extra) {
|
||||||
this.extra.add(extra);
|
this.extra.add(extra);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setText(String text) {
|
public TellrawPart setText(String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawEvent<TellrawEvent.HoverAction> getHoverEvent() {
|
public TellrawEvent<TellrawEvent.HoverAction> getHoverEvent() {
|
||||||
return hoverEvent;
|
return hoverEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setHoverEvent(TellrawEvent<TellrawEvent.HoverAction> hoverEvent) {
|
public TellrawPart setHoverEvent(TellrawEvent<TellrawEvent.HoverAction> hoverEvent) {
|
||||||
this.hoverEvent = hoverEvent;
|
this.hoverEvent = hoverEvent;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawEvent<TellrawEvent.ClickAction> getClickEvent() {
|
public TellrawEvent<TellrawEvent.ClickAction> getClickEvent() {
|
||||||
return clickEvent;
|
return clickEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TellrawPart setClickEvent(TellrawEvent<TellrawEvent.ClickAction> clickEvent) {
|
public TellrawPart setClickEvent(TellrawEvent<TellrawEvent.ClickAction> clickEvent) {
|
||||||
this.clickEvent = clickEvent;
|
this.clickEvent = clickEvent;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,59 +1,59 @@
|
||||||
package buttondevteam.chat.formatting;
|
package buttondevteam.chat.components.formatter.formatting;
|
||||||
|
|
||||||
import java.io.IOException;
|
import buttondevteam.lib.chat.TellrawSerializableEnum;
|
||||||
import java.lang.reflect.Type;
|
import com.google.gson.*;
|
||||||
import java.util.Collection;
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
import com.google.gson.*;
|
|
||||||
import com.google.gson.stream.*;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import buttondevteam.lib.chat.TellrawSerializableEnum;
|
import java.util.Collection;
|
||||||
|
|
||||||
public abstract class TellrawSerializer {
|
public abstract class TellrawSerializer {
|
||||||
public static class TwEnum extends TypeAdapter<TellrawSerializableEnum> {
|
public static class TwEnum extends TypeAdapter<TellrawSerializableEnum> {
|
||||||
@Override
|
@Override
|
||||||
public TellrawSerializableEnum read(JsonReader reader) throws IOException {
|
public TellrawSerializableEnum read(JsonReader reader) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JsonWriter writer, TellrawSerializableEnum enumval) throws IOException {
|
public void write(JsonWriter writer, TellrawSerializableEnum enumval) throws IOException {
|
||||||
if (enumval == null)
|
if (enumval == null)
|
||||||
writer.nullValue();
|
writer.nullValue();
|
||||||
else
|
else
|
||||||
writer.value(enumval.getName());
|
writer.value(enumval.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TwCollection implements JsonSerializer<Collection<?>> {
|
public static class TwCollection implements JsonSerializer<Collection<?>> {
|
||||||
@Override
|
@Override
|
||||||
public JsonElement serialize(Collection<?> src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(Collection<?> src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
if (src == null || src.isEmpty())
|
if (src == null || src.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
JsonArray array = new JsonArray();
|
JsonArray array = new JsonArray();
|
||||||
|
|
||||||
for (Object child : src) {
|
for (Object child : src) {
|
||||||
JsonElement element = context.serialize(child);
|
JsonElement element = context.serialize(child);
|
||||||
array.add(element);
|
array.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TwBool extends TypeAdapter<Boolean> {
|
public static class TwBool extends TypeAdapter<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
public Boolean read(JsonReader reader) throws IOException {
|
public Boolean read(JsonReader reader) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JsonWriter writer, Boolean val) throws IOException {
|
public void write(JsonWriter writer, Boolean val) throws IOException {
|
||||||
if (val)
|
if (val)
|
||||||
writer.value(val);
|
writer.value(val);
|
||||||
else
|
else
|
||||||
writer.nullValue();
|
writer.nullValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,9 @@ import buttondevteam.lib.chat.*;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@CommandClass(path = "u c", helpText = {
|
@CommandClass(path = "u c", helpText = {
|
||||||
"Rainbow mode",
|
"Rainbow mode",
|
||||||
"This command allows you to talk in rainbow colors"
|
"This command allows you to talk in rainbow colors"
|
||||||
|
@ -16,7 +19,7 @@ public class CCommand extends ICommand2MC {
|
||||||
public boolean def(Player player, @Command2.OptionalArg String color) {
|
public boolean def(Player player, @Command2.OptionalArg String color) {
|
||||||
ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class);
|
ChatPlayer p = TBMCPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class);
|
||||||
if (color == null) {
|
if (color == null) {
|
||||||
if (PluginMain.permission.has(player, "thorpe.color.rainbow")) {
|
if (PluginMain.permission.has(player, "chroma.color.rainbow")) {
|
||||||
p.RainbowPresserColorMode = !p.RainbowPresserColorMode;
|
p.RainbowPresserColorMode = !p.RainbowPresserColorMode;
|
||||||
p.OtherColorMode = null;
|
p.OtherColorMode = null;
|
||||||
if (p.RainbowPresserColorMode)
|
if (p.RainbowPresserColorMode)
|
||||||
|
@ -28,19 +31,23 @@ public class CCommand extends ICommand2MC {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (PluginMain.permission.has(player, "thorpe.color.custom")) {
|
if (PluginMain.permission.has(player, "chroma.color.custom")) {
|
||||||
p.RainbowPresserColorMode = false;
|
String x = color.toLowerCase();
|
||||||
p.OtherColorMode = null;
|
if ("off".equals(x)) {
|
||||||
try {
|
p.OtherColorMode = null;
|
||||||
p.OtherColorMode = Color.valueOf(color.toLowerCase());
|
player.sendMessage("§eMessage color reset.");
|
||||||
} catch (Exception e) {
|
return true;
|
||||||
|
}
|
||||||
|
Optional<Color> oc = Arrays.stream(Color.values()).filter(c -> c.getName().equals(x)).findAny();
|
||||||
|
if (!oc.isPresent()) {
|
||||||
player.sendMessage("§cUnknown message color: " + color);
|
player.sendMessage("§cUnknown message color: " + color);
|
||||||
player.sendMessage("§cUse color names, like blue, or dark_aqua");
|
player.sendMessage("§cUse color names, like blue, or dark_aqua");
|
||||||
|
player.sendMessage("§cOr use 'off' to disable");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (p.OtherColorMode != null)
|
p.RainbowPresserColorMode = false;
|
||||||
player.sendMessage(String.format("§eMessage color set to %s", p.OtherColorMode));
|
p.OtherColorMode = oc.get();
|
||||||
else
|
player.sendMessage(String.format("§eMessage color set to %s", p.OtherColorMode));
|
||||||
player.sendMessage("§eMessage color reset.");
|
|
||||||
} else {
|
} else {
|
||||||
player.sendMessage("§cYou don't have permission for this command.");
|
player.sendMessage("§cYou don't have permission for this command.");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -3,10 +3,10 @@ package buttondevteam.chat.components.fun;
|
||||||
import buttondevteam.chat.ChatPlayer;
|
import buttondevteam.chat.ChatPlayer;
|
||||||
import buttondevteam.chat.PluginMain;
|
import buttondevteam.chat.PluginMain;
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
|
import buttondevteam.lib.ChromaUtils;
|
||||||
import buttondevteam.lib.TBMCChatEventBase;
|
import buttondevteam.lib.TBMCChatEventBase;
|
||||||
import buttondevteam.lib.TBMCCommandPreprocessEvent;
|
import buttondevteam.lib.TBMCCommandPreprocessEvent;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.ThorpeUtils;
|
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.architecture.ConfigData;
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
|
@ -139,15 +139,15 @@ public class FunComponent extends Component<PluginMain> implements Listener {
|
||||||
if (ht.getName().equalsIgnoreCase(cmd))
|
if (ht.getName().equalsIgnoreCase(cmd))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (PluginMain.permission.has(event.getSender(), "thorpe.unanything")) {
|
if (PluginMain.permission.has(event.getSender(), "chroma.unanything")) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
String s = cmd.substring(3);
|
int index = cmd.lastIndexOf(' ');
|
||||||
int index = event.getMessage().indexOf(' ');
|
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
event.getSender().sendMessage("§cUsage: /un" + s + " <player>");
|
event.getSender().sendMessage("§cUsage: " + cmd + " <player>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Player target = Bukkit.getPlayer(event.getMessage().substring(index + 1));
|
String s = cmd.substring(3, index);
|
||||||
|
Player target = Bukkit.getPlayer(cmd.substring(index + 1));
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
event.getSender().sendMessage("§cError: Player not found. (/un" + s + " <player>)");
|
event.getSender().sendMessage("§cError: Player not found. (/un" + s + " <player>)");
|
||||||
return;
|
return;
|
||||||
|
@ -155,7 +155,7 @@ public class FunComponent extends Component<PluginMain> implements Listener {
|
||||||
val user = ChromaGamerBase.getFromSender(event.getSender());
|
val user = ChromaGamerBase.getFromSender(event.getSender());
|
||||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 10 * 20, 5, false, false));
|
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 10 * 20, 5, false, false));
|
||||||
val chan = user.channel().get();
|
val chan = user.channel().get();
|
||||||
TBMCChatAPI.SendSystemMessage(chan, chan.getRTR(event.getSender()), ThorpeUtils.getDisplayName(event.getSender()) + " un" + s
|
TBMCChatAPI.SendSystemMessage(chan, chan.getRTR(event.getSender()), ChromaUtils.getDisplayName(event.getSender()) + " un" + s
|
||||||
+ "'d " + target.getDisplayName(), unlolTarget);
|
+ "'d " + target.getDisplayName(), unlolTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package buttondevteam.chat.components.fun;
|
package buttondevteam.chat.components.fun;
|
||||||
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.core.component.restart.RestartComponent;
|
|
||||||
import buttondevteam.core.component.restart.ScheduledRestartCommand;
|
import buttondevteam.core.component.restart.ScheduledRestartCommand;
|
||||||
|
import buttondevteam.lib.ChromaUtils;
|
||||||
import buttondevteam.lib.ScheduledServerRestartEvent;
|
import buttondevteam.lib.ScheduledServerRestartEvent;
|
||||||
import buttondevteam.lib.ThorpeUtils;
|
|
||||||
import buttondevteam.lib.chat.Command2;
|
import buttondevteam.lib.chat.Command2;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.chat.ICommand2MC;
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
@ -33,7 +31,7 @@ public class PressCommand extends ICommand2MC implements Listener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pressers.add(sender);
|
pressers.add(sender);
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("§b-- %s §bpressed at %.0fs", ThorpeUtils.getDisplayName(sender), command.getRestartCounter() / 20f), 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);
|
command.setRestartCounter(startTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package buttondevteam.chat.components.fun;
|
package buttondevteam.chat.components.fun;
|
||||||
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
|
import buttondevteam.lib.ChromaUtils;
|
||||||
import buttondevteam.lib.TBMCChatEventBase;
|
import buttondevteam.lib.TBMCChatEventBase;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.ThorpeUtils;
|
import buttondevteam.lib.chat.Command2;
|
||||||
import buttondevteam.lib.chat.*;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
@ -39,9 +41,9 @@ public final class UnlolCommand extends ICommand2MC {
|
||||||
if (lol.Lolowner instanceof Player)
|
if (lol.Lolowner instanceof Player)
|
||||||
((Player) lol.Lolowner)
|
((Player) lol.Lolowner)
|
||||||
.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 2 * 20, 5, false, false));
|
.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 2 * 20, 5, false, false));
|
||||||
String msg = ThorpeUtils.getDisplayName(sender)
|
String msg = ChromaUtils.getDisplayName(sender)
|
||||||
+ (lol.Lolornot ? " unlolled " : " unlaughed ")
|
+ (lol.Lolornot ? " unlolled " : " unlaughed ")
|
||||||
+ ThorpeUtils.getDisplayName(lol.Lolowner);
|
+ ChromaUtils.getDisplayName(lol.Lolowner);
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, msg, target);
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, msg, target);
|
||||||
Lastlol.remove(lol.Chatevent.getChannel());
|
Lastlol.remove(lol.Chatevent.getChannel());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -15,7 +15,6 @@ import com.earth2me.essentials.User;
|
||||||
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
||||||
import com.palmergames.bukkit.towny.object.Nation;
|
import com.palmergames.bukkit.towny.object.Nation;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.var;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
@ -113,6 +112,7 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
|
||||||
if (useNationColors().get())
|
if (useNationColors().get())
|
||||||
registerCommand(new buttondevteam.chat.components.towncolors.admin.NationColorCommand());
|
registerCommand(new buttondevteam.chat.components.towncolors.admin.NationColorCommand());
|
||||||
registerCommand(new TCCount());
|
registerCommand(new TCCount());
|
||||||
|
registerCommand(new NColorCommand());
|
||||||
registerListener(new TownyListener());
|
registerListener(new TownyListener());
|
||||||
registerListener(this);
|
registerListener(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class NationColorCommand extends AdminCommandBase {
|
||||||
if (!c.get().getName().equals(Color.White.getName())) { //Default nation color
|
if (!c.get().getName().equals(Color.White.getName())) { //Default nation color
|
||||||
for (val e : TownColorComponent.NationColor.entrySet()) {
|
for (val e : TownColorComponent.NationColor.entrySet()) {
|
||||||
if (e.getValue().getName().equals(c.get().getName())) {
|
if (e.getValue().getName().equals(c.get().getName())) {
|
||||||
sender.sendMessage("§The nation " + e.getKey() + " already uses this color!");
|
sender.sendMessage("§cThe nation " + e.getKey() + " already uses this color!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class TownColorCommand extends AdminCommandBase { //TODO: Command path al
|
||||||
val c = getColorOrSendError(colors[i], sender);
|
val c = getColorOrSendError(colors[i], sender);
|
||||||
if (!c.isPresent())
|
if (!c.isPresent())
|
||||||
return true;
|
return true;
|
||||||
clrs[i - 1] = c.get();
|
clrs[i] = c.get();
|
||||||
}
|
}
|
||||||
Color tnc;
|
Color tnc;
|
||||||
boolean usenc = TownColorComponent.getComponent().useNationColors().get();
|
boolean usenc = TownColorComponent.getComponent().useNationColors().get();
|
||||||
|
|
|
@ -1,23 +1,33 @@
|
||||||
package buttondevteam.chat.components.towny;
|
package buttondevteam.chat.components.towny;
|
||||||
|
|
||||||
import buttondevteam.chat.ChatProcessing;
|
import buttondevteam.chat.ChatUtils;
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import com.palmergames.bukkit.towny.TownyLogger;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.core.Filter;
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.Logger;
|
||||||
|
import org.apache.logging.log4j.core.LoggerContext;
|
||||||
|
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||||
|
import org.apache.logging.log4j.core.filter.LevelRangeFilter;
|
||||||
|
import org.apache.logging.log4j.core.layout.PatternLayout;
|
||||||
|
|
||||||
import java.util.logging.Handler;
|
|
||||||
import java.util.logging.LogRecord;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class TownyAnnouncer {
|
public class TownyAnnouncer {
|
||||||
private static final Pattern LOG_TYPE_PATTERN = Pattern.compile("\\[(\\w+) (?:Msg|Message)](?: (\\w+):)?");
|
private static final Pattern LOG_TYPE_PATTERN = Pattern.compile("\\[(\\w+) (?:Msg|Message)](?: (\\w+):)?");
|
||||||
private static final Handler HANDLER = new Handler() {
|
private static final String APPENDER_NAME = "Chroma";
|
||||||
|
private static final AbstractAppender HANDLER = new AbstractAppender(APPENDER_NAME,
|
||||||
|
LevelRangeFilter.createFilter(Level.INFO, Level.INFO, Filter.Result.ACCEPT, Filter.Result.ACCEPT),
|
||||||
|
PatternLayout.createDefaultLayout()) {
|
||||||
@Override
|
@Override
|
||||||
public void publish(LogRecord logRecord) {
|
public void append(LogEvent logRecord) {
|
||||||
if (logRecord.getMessage() == null) return;
|
if (logRecord.getMessage() == null) return;
|
||||||
val m = LOG_TYPE_PATTERN.matcher(logRecord.getMessage());
|
String message = logRecord.getMessage().getFormattedMessage();
|
||||||
|
val m = LOG_TYPE_PATTERN.matcher(message);
|
||||||
if (!m.find()) return;
|
if (!m.find()) return;
|
||||||
String groupID = m.group(2); //The group ID is correctly cased
|
String groupID = m.group(2); //The group ID is correctly cased
|
||||||
switch (String.valueOf(m.group(1))) { //valueOf: Handles null
|
switch (String.valueOf(m.group(1))) { //valueOf: Handles null
|
||||||
|
@ -25,31 +35,21 @@ public class TownyAnnouncer {
|
||||||
if (townChannel == null) return;
|
if (townChannel == null) return;
|
||||||
TBMCChatAPI.SendSystemMessage(townChannel,
|
TBMCChatAPI.SendSystemMessage(townChannel,
|
||||||
new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, false), groupID),
|
new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, false), groupID),
|
||||||
logRecord.getMessage(), target, ChatProcessing.MCORIGIN);
|
message, target, ChatUtils.MCORIGIN);
|
||||||
break;
|
break;
|
||||||
case "Nation":
|
case "Nation":
|
||||||
if (nationChannel == null) return;
|
if (nationChannel == null) return;
|
||||||
TBMCChatAPI.SendSystemMessage(nationChannel,
|
TBMCChatAPI.SendSystemMessage(nationChannel,
|
||||||
new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, true), groupID),
|
new Channel.RecipientTestResult(TownyComponent.getTownNationIndex(groupID, true), groupID),
|
||||||
logRecord.getMessage(), target, ChatProcessing.MCORIGIN);
|
message, target, ChatUtils.MCORIGIN);
|
||||||
break;
|
break;
|
||||||
case "Global":
|
case "Global":
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat,
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat,
|
||||||
Channel.RecipientTestResult.ALL,
|
Channel.RecipientTestResult.ALL,
|
||||||
logRecord.getMessage(), target, ChatProcessing.MCORIGIN);
|
message, target, ChatUtils.MCORIGIN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flush() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws SecurityException {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static TBMCSystemChatEvent.BroadcastTarget target;
|
private static TBMCSystemChatEvent.BroadcastTarget target;
|
||||||
|
@ -60,7 +60,23 @@ public class TownyAnnouncer {
|
||||||
target = TBMCSystemChatEvent.BroadcastTarget.add("towny");
|
target = TBMCSystemChatEvent.BroadcastTarget.add("towny");
|
||||||
TownyAnnouncer.townChannel = townChannel;
|
TownyAnnouncer.townChannel = townChannel;
|
||||||
TownyAnnouncer.nationChannel = nationChannel;
|
TownyAnnouncer.nationChannel = nationChannel;
|
||||||
TownyLogger.log.addHandler(HANDLER);
|
/*System.out.println(LogManager.getLogger("com.palmergames.bukkit.towny"));
|
||||||
|
((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getContext().getConfiguration().addAppender(HANDLER);
|
||||||
|
System.out.println(((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders());
|
||||||
|
((LoggerContext)LogManager.getContext(false)).updateLoggers();
|
||||||
|
System.out.println(((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders());
|
||||||
|
((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getContext().updateLoggers();
|
||||||
|
System.out.println(((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders());*/
|
||||||
|
val lc = (LoggerContext) LogManager.getContext(false);
|
||||||
|
HANDLER.start();
|
||||||
|
lc.getConfiguration().addAppender(HANDLER);
|
||||||
|
Logger logger = lc.getLogger("com.palmergames.bukkit.towny");
|
||||||
|
//System.out.println(logger);
|
||||||
|
//System.out.println(lc.getConfiguration().<Appender>getAppender(HANDLER.getName())); //T defaults to String because of the context which results in a cast exception
|
||||||
|
logger.addAppender(lc.getConfiguration().getAppender(HANDLER.getName()));
|
||||||
|
logger.get().addAppender(HANDLER, Level.INFO, HANDLER.getFilter());
|
||||||
|
lc.updateLoggers();
|
||||||
|
//System.out.println(logger.getAppenders());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setdown() {
|
public static void setdown() {
|
||||||
|
@ -68,6 +84,6 @@ public class TownyAnnouncer {
|
||||||
target = null;
|
target = null;
|
||||||
TownyAnnouncer.townChannel = null;
|
TownyAnnouncer.townChannel = null;
|
||||||
TownyAnnouncer.nationChannel = null;
|
TownyAnnouncer.nationChannel = null;
|
||||||
TownyLogger.log.removeHandler(HANDLER);
|
((Logger) LogManager.getLogger("com.palmergames.bukkit.towny")).getAppenders().remove(APPENDER_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
package buttondevteam.chat.components.towny;
|
package buttondevteam.chat.components.towny;
|
||||||
|
|
||||||
import buttondevteam.chat.PluginMain;
|
import buttondevteam.chat.PluginMain;
|
||||||
import buttondevteam.chat.formatting.TellrawPart;
|
import buttondevteam.chat.VanillaUtils;
|
||||||
|
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.chat.Color;
|
import buttondevteam.lib.chat.Color;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import com.palmergames.bukkit.towny.Towny;
|
import com.palmergames.bukkit.towny.TownyUniverse;
|
||||||
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
||||||
import com.palmergames.bukkit.towny.object.Nation;
|
import com.palmergames.bukkit.towny.object.Nation;
|
||||||
import com.palmergames.bukkit.towny.object.Resident;
|
import com.palmergames.bukkit.towny.object.Resident;
|
||||||
import com.palmergames.bukkit.towny.object.Town;
|
import com.palmergames.bukkit.towny.object.Town;
|
||||||
import com.palmergames.bukkit.towny.object.TownyUniverse;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public class TownyComponent extends Component<PluginMain> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
TU = ((Towny) Bukkit.getPluginManager().getPlugin("Towny")).getTownyUniverse();
|
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
|
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
|
Nations = TU.getNationsMap().values().stream().map(Nation::getName).collect(Collectors.toCollection(ArrayList::new)); // Same here but with nations
|
||||||
TBMCChatAPI.RegisterChatChannel(
|
TBMCChatAPI.RegisterChatChannel(
|
||||||
|
@ -47,12 +47,20 @@ public class TownyComponent extends Component<PluginMain> {
|
||||||
TownyAnnouncer.setdown();
|
TownyAnnouncer.setdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleSpies(Channel channel, TellrawPart json, Function<TellrawPart, String> toJson) {
|
public void handleSpiesInit(Channel channel, TellrawPart json, Function<TellrawPart, String> toJson) {
|
||||||
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
|
if (channel.ID.equals(TownChat.ID) || channel.ID.equals(NationChat.ID)) {
|
||||||
((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]"));
|
((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]"));
|
||||||
String jsonstr = toJson.apply(json);
|
jsonstr = toJson.apply(json);
|
||||||
Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format(
|
}
|
||||||
"tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr));
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
package buttondevteam.chat.listener;
|
package buttondevteam.chat.listener;
|
||||||
|
|
||||||
import buttondevteam.chat.ChatPlayer;
|
import buttondevteam.chat.ChatPlayer;
|
||||||
import buttondevteam.chat.ChatProcessing;
|
import buttondevteam.chat.ChatUtils;
|
||||||
import buttondevteam.chat.PluginMain;
|
import buttondevteam.chat.PluginMain;
|
||||||
import buttondevteam.chat.commands.ucmds.HistoryCommand;
|
import buttondevteam.chat.commands.ucmds.HistoryCommand;
|
||||||
import buttondevteam.chat.components.flair.FlairComponent;
|
import buttondevteam.chat.components.flair.FlairComponent;
|
||||||
|
import buttondevteam.chat.components.formatter.FormatterComponent;
|
||||||
import buttondevteam.chat.components.towncolors.TownColorComponent;
|
import buttondevteam.chat.components.towncolors.TownColorComponent;
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.core.component.channel.ChatChannelRegisterEvent;
|
|
||||||
import buttondevteam.core.component.channel.ChatRoom;
|
import buttondevteam.core.component.channel.ChatRoom;
|
||||||
|
import buttondevteam.lib.ChromaUtils;
|
||||||
import buttondevteam.lib.TBMCChatEvent;
|
import buttondevteam.lib.TBMCChatEvent;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.ThorpeUtils;
|
|
||||||
import buttondevteam.lib.chat.ChatMessage;
|
import buttondevteam.lib.chat.ChatMessage;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.player.ChromaGamerBase;
|
import buttondevteam.lib.player.ChromaGamerBase;
|
||||||
|
@ -52,7 +52,8 @@ public class PlayerListener implements Listener {
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
//The custom event is called in the core, but doesn't cancel the MC event
|
//The custom event is called in the core, but doesn't cancel the MC event
|
||||||
event.setCancelled(true); // The custom event should only be cancelled when muted or similar
|
if (ComponentManager.isEnabled(FormatterComponent.class)) //If not enabled, then let the other plugins deal with the message
|
||||||
|
event.setCancelled(true); // The custom event should only be cancelled when muted or similar
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
@ -95,11 +96,11 @@ public class PlayerListener implements Listener {
|
||||||
Player player = Bukkit.getPlayer(message.substring(index + 1));
|
Player player = Bukkit.getPlayer(message.substring(index + 1));
|
||||||
if (player != null && sender instanceof Player)
|
if (player != null && sender instanceof Player)
|
||||||
player.sendMessage("§b" + ((Player) sender).getDisplayName() + " §bis in this world: " //TODO: Move to the Core
|
player.sendMessage("§b" + ((Player) sender).getDisplayName() + " §bis in this world: " //TODO: Move to the Core
|
||||||
+ ((Player) sender).getWorld().getName());
|
+ ((Player) sender).getWorld().getName());
|
||||||
} else if (cmd.equalsIgnoreCase("minecraft:me")) {
|
} else if (cmd.equalsIgnoreCase("minecraft:me")) {
|
||||||
if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) {
|
if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) {
|
||||||
String msg = message.substring(index + 1);
|
String msg = message.substring(index + 1);
|
||||||
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("* %s %s", ThorpeUtils.getDisplayName(sender), msg), TBMCSystemChatEvent.BroadcastTarget.ALL); //TODO: Don't send to all
|
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, Channel.RecipientTestResult.ALL, String.format("* %s %s", ChromaUtils.getDisplayName(sender), msg), TBMCSystemChatEvent.BroadcastTarget.ALL); //TODO: Don't send to all
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("§cCan't use /minecraft:me while muted.");
|
sender.sendMessage("§cCan't use /minecraft:me while muted.");
|
||||||
|
@ -131,7 +132,7 @@ public class PlayerListener implements Listener {
|
||||||
String name = e.getLastToken();
|
String name = e.getLastToken();
|
||||||
for (Entry<String, UUID> nicknamekv : nicknames.entrySet()) {
|
for (Entry<String, UUID> nicknamekv : nicknames.entrySet()) {
|
||||||
if (nicknamekv.getKey().startsWith(name.toLowerCase()))
|
if (nicknamekv.getKey().startsWith(name.toLowerCase()))
|
||||||
e.getTabCompletions().add(PluginMain.essentials.getUser(Bukkit.getPlayer(nicknamekv.getValue())).getNick(true)); //Tabcomplete with the correct case
|
e.getTabCompletions().add(PluginMain.essentials.getUser(Bukkit.getPlayer(nicknamekv.getValue())).getNick(true)); //Tabcomplete with the correct case
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +155,7 @@ public class PlayerListener implements Listener {
|
||||||
if (flair.length() > 0)
|
if (flair.length() > 0)
|
||||||
e.addInfo("/r/TheButton flair: " + flair);
|
e.addInfo("/r/TheButton flair: " + flair);
|
||||||
}
|
}
|
||||||
e.addInfo(String.format("Respect: %.2f", cp.getF()));
|
e.addInfo(String.format("Respect: %.2f", cp.getF()));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
TBMCCoreAPI.SendException("Error while providing chat info for player " + e.getPlayer().getFileName(), ex);
|
TBMCCoreAPI.SendException("Error while providing chat info for player " + e.getPlayer().getFileName(), ex);
|
||||||
}
|
}
|
||||||
|
@ -166,31 +167,20 @@ public class PlayerListener implements Listener {
|
||||||
if (e.isCancelled())
|
if (e.isCancelled())
|
||||||
return;
|
return;
|
||||||
HistoryCommand.addChatMessage(e.getCm(), e.getChannel());
|
HistoryCommand.addChatMessage(e.getCm(), e.getChannel());
|
||||||
e.setCancelled(ChatProcessing.ProcessChat(e));
|
e.setCancelled(FormatterComponent.handleChat(e));
|
||||||
} catch (NoClassDefFoundError | Exception ex) { // Weird things can happen
|
} catch (NoClassDefFoundError | Exception ex) { // Weird things can happen
|
||||||
val str = "§c!§r[" + e.getChannel().DisplayName().get() + "] <"
|
ChatUtils.sendChatMessage(e, s -> "§c!§r" + s);
|
||||||
+ ThorpeUtils.getDisplayName(e.getSender()) + "> " + e.getMessage();
|
|
||||||
for (Player p : Bukkit.getOnlinePlayers())
|
|
||||||
if (e.shouldSendTo(p))
|
|
||||||
p.sendMessage(str);
|
|
||||||
Bukkit.getConsoleSender().sendMessage(str);
|
|
||||||
TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex);
|
TBMCCoreAPI.SendException("An error occured while processing a chat message!", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onChannelRegistered(ChatChannelRegisterEvent e) {
|
|
||||||
if (!e.getChannel().isGlobal() && PluginMain.SB.getObjective(e.getChannel().ID) == null) // Not global chat and doesn't exist yet
|
|
||||||
PluginMain.SB.registerNewObjective(e.getChannel().ID, "dummy");
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onNickChange(NickChangeEvent e) {
|
public void onNickChange(NickChangeEvent e) {
|
||||||
String nick = e.getValue();
|
String nick = e.getValue();
|
||||||
if (nick == null)
|
if (nick == null)
|
||||||
nicknames.inverse().remove(e.getAffected().getBase().getUniqueId());
|
nicknames.inverse().remove(e.getAffected().getBase().getUniqueId());
|
||||||
else
|
else
|
||||||
nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase());
|
nicknames.inverse().forcePut(e.getAffected().getBase().getUniqueId(), ChatColor.stripColor(nick).toLowerCase());
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
|
Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
|
||||||
TownColorComponent.updatePlayerColors(e.getAffected().getBase()); //Won't fire this event again
|
TownColorComponent.updatePlayerColors(e.getAffected().getBase()); //Won't fire this event again
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: Thorpe-Chat
|
name: Chroma-Chat
|
||||||
main: buttondevteam.chat.PluginMain
|
main: buttondevteam.chat.PluginMain
|
||||||
version: 4.0
|
version: 4.0
|
||||||
commands:
|
commands:
|
||||||
|
@ -34,7 +34,7 @@ author: NorbiPeti
|
||||||
depend:
|
depend:
|
||||||
- Essentials
|
- Essentials
|
||||||
- Vault
|
- Vault
|
||||||
- ThorpeCore
|
- ChromaCore
|
||||||
soft-depend:
|
soft-depend:
|
||||||
- Minigames
|
- Minigames
|
||||||
- Dynmap-Towny
|
- Dynmap-Towny
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
package buttondevteam.chat;
|
package buttondevteam.chat.components.formatter;
|
||||||
|
|
||||||
|
import buttondevteam.chat.ChatUtils;
|
||||||
|
import buttondevteam.chat.ObjectTestRunner;
|
||||||
import buttondevteam.chat.ObjectTestRunner.Objects;
|
import buttondevteam.chat.ObjectTestRunner.Objects;
|
||||||
|
import buttondevteam.chat.PluginMain;
|
||||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||||
import buttondevteam.chat.formatting.ChatFormatter;
|
import buttondevteam.chat.components.formatter.formatting.ChatFormatter;
|
||||||
import buttondevteam.chat.formatting.TellrawEvent;
|
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
|
||||||
import buttondevteam.chat.formatting.TellrawEvent.ClickAction;
|
import buttondevteam.chat.components.formatter.formatting.TellrawEvent.ClickAction;
|
||||||
import buttondevteam.chat.formatting.TellrawEvent.HoverAction;
|
import buttondevteam.chat.components.formatter.formatting.TellrawEvent.HoverAction;
|
||||||
import buttondevteam.chat.formatting.TellrawPart;
|
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
|
||||||
import buttondevteam.core.TestPrepare;
|
import buttondevteam.core.TestPrepare;
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.lib.chat.Color;
|
import buttondevteam.lib.chat.Color;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
@ -19,8 +23,6 @@ import org.mockito.Mockito;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
@RunWith(ObjectTestRunner.class)
|
@RunWith(ObjectTestRunner.class)
|
||||||
public class ChatFormatIT {
|
public class ChatFormatIT {
|
||||||
@Objects
|
@Objects
|
||||||
|
@ -91,16 +93,16 @@ public class ChatFormatIT {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMessage() {
|
public void testMessage() {
|
||||||
ArrayList<ChatFormatter> cfs = ChatProcessing.addFormatters(Color.White);
|
ArrayList<ChatFormatter> cfs = ChatProcessing.addFormatters(Color.White, p -> true);
|
||||||
final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatProcessing.MCORIGIN);
|
final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN);
|
||||||
final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN);
|
final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
|
||||||
ChatFormatter.Combine(cfs, message, tp);
|
ChatFormatter.Combine(cfs, message, tp, null);
|
||||||
System.out.println("Testing: " + message);
|
System.out.println("Testing: " + message);
|
||||||
// System.out.println(ChatProcessing.toJson(tp));
|
// System.out.println(ChatProcessing.toJson(tp));
|
||||||
final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatProcessing.MCORIGIN);
|
final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
|
||||||
// System.out.println("Raw: " + ChatProcessing.toJson(expectedtp));
|
// System.out.println("Raw: " + ChatProcessing.toJson(expectedtp));
|
||||||
for (TellrawPart extra : extras)
|
for (TellrawPart extra : extras)
|
||||||
expectedtp.addExtra(extra);
|
expectedtp.addExtra(extra);
|
||||||
assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp));
|
Assert.assertEquals(ChatProcessing.toJson(expectedtp), ChatProcessing.toJson(tp));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue