Merge branch 'dev'
# Conflicts: # .idea/ButtonChat.iml
This commit is contained in:
commit
f3ec9e7870
26 changed files with 751 additions and 763 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -69,14 +69,12 @@ build/
|
|||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
|
@ -195,7 +193,6 @@ $RECYCLE.BIN/
|
|||
*.egg
|
||||
*.egg-info
|
||||
dist/
|
||||
build/
|
||||
eggs/
|
||||
parts/
|
||||
var/
|
||||
|
@ -217,7 +214,7 @@ pip-log.txt
|
|||
.mr.developer.cfg
|
||||
.metadata/*
|
||||
TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar
|
||||
#*.iml
|
||||
*.iml
|
||||
*.name
|
||||
.idea/compiler.xml
|
||||
*.xml
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_11">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<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/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.guava:guava:21.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.19" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.md-5:bungeecord-chat:1.12-SNAPSHOT" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.TBMCPlugins.ChromaCore:Chroma-Core:master-59aa13cd74-1" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sourceforge.htmlcleaner:htmlcleaner:2.16" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jdom:jdom2:2.0.5" 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: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: net.ess3:EssentialsX:2.17.1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: io.papermc:paperlib:1.0.2" 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.2.0" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.milkbowl:VaultAPI:master-89c00e1cb8-1" 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" 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.nijikokun.bukkit:Permissions:3.1.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bukkit:bukkit:1.7.10-R0.1-SNAPSHOT" level="project" />
|
||||
<orderEntry type="library" name="Maven: ru.tehkode:PermissionsEx:1.19.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: de.bananaco:bPermissions:2.9.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.platymuus.bukkit.permissions:PermissionsBukkit:1.6" 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: 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>
|
||||
</module>
|
16
.travis.yml
16
.travis.yml
|
@ -7,21 +7,17 @@ before_install: | # Wget BuildTools and run if cached folder not found
|
|||
# grep so that download counts don't appear in log files
|
||||
java -jar BuildTools.jar --rev 1.12.2 | grep -vE "[^/ ]*/[^/ ]*\s*KB\s*$" | grep -v "^\s*$"
|
||||
fi
|
||||
cp ci/settings.xml $HOME/.m2/
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
sudo: true
|
||||
dist: trusty # Needed for Java 8, although we might not need Java 8
|
||||
deploy:
|
||||
# deploy develop to the staging environment
|
||||
- provider: script
|
||||
script: chmod +x deploy.sh && sh deploy.sh staging
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "F5YiEuD6LyRENUDMCslcSl0O0dg4IDk+nNeb4X2VLYlmb8dW9beMuIgjH8efTMeaQ3D/ntIkN0Dtf2GKvpOduhwkSbAgw4WM028X60SY9f2hmpEO3LmM4T1tKoDlI1T3BmhYP4KeTKBYn+etV1mSPbT07vUybCm/vGzvr96yMZGNFEoKsWLaEu7dZfBFULj4tXOwrLh/KO6BsdAHvZcGKWNVupPq3YoUVT0dpGcUudf5cpn+aaqMwyd709zgMbyCuqf+c5Udps43q4EKvr9z7TWxFUkGTPVVAcUVygJsi2ytuyA8TLMPq/KhYe9htnkNUnizbqv/j49xww0gVaD7OJXENJ4hAUTV4sdn1DXG45JXW+dir3V7YzbRYn3M+eCuKB2O77SXRZBkxcGtTMtCmghP9/tcRAQlXDXnxu7oAnlUVp17g/+aFApvlzZEZVx2N+fkyEe7JrUFlRCixtHyrmTLWhyV0Px9p0FHJpvSSCL0S0UKVAT/sNHYHhD5gouK7owEomEbG58XCsRDH6Et7RuDksB98ekK8brZp6S7dNIS2CVuVx1vIkXC8PzUGcpJQoztvEYUE20Axahh5s8AkE9n/O9jzs9ajcfYaHhWzYeUZzHdHllOYF9l6VoCUitTk4Sl8eJifSq3GzI+T6wGMBepZHLpe230MvBIrqGZ+Vg="
|
||||
file: 'Chroma-Core/target/Chroma-Core.jar'
|
||||
on:
|
||||
branch: dev
|
||||
skip_cleanup: true
|
||||
# deploy master to production
|
||||
- provider: script
|
||||
script: chmod +x deploy.sh && sh deploy.sh production
|
||||
on:
|
||||
branch: master
|
||||
tags: true
|
||||
skip_cleanup: true
|
||||
|
|
1
Mvn.txt
1
Mvn.txt
|
@ -1 +0,0 @@
|
|||
apache-maven-3.2.5/bin/mvn install:install-file -Dfile=Towny.jar -DgroupId=com.palmergames -DartifactId=Towny -Dversion=0.90.0.0 -Dpackaging=jar
|
36
ci/settings.xml
Normal file
36
ci/settings.xml
Normal file
|
@ -0,0 +1,36 @@
|
|||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
http://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
|
||||
<activeProfiles>
|
||||
<activeProfile>github</activeProfile>
|
||||
</activeProfiles>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>github</id>
|
||||
<repositories>
|
||||
<!-- <repository>
|
||||
<id>central</id>
|
||||
<url>https://repo1.maven.org/maven2</url>
|
||||
<releases><enabled>true</enabled></releases>
|
||||
<snapshots><enabled>false</enabled></snapshots>
|
||||
</repository> -->
|
||||
<repository>
|
||||
<id>github</id>
|
||||
<name>GitHub Towny Apache Maven Packages</name>
|
||||
<url>https://maven.pkg.github.com/TownyAdvanced/Towny</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<servers>
|
||||
<server>
|
||||
<id>github</id>
|
||||
<username>NorbiPeti</username>
|
||||
<password>${env.GHTOKEN}</password>
|
||||
</server>
|
||||
</servers>
|
||||
</settings>
|
10
deploy.sh
10
deploy.sh
|
@ -1,10 +0,0 @@
|
|||
#!/bin/sh
|
||||
FILENAME=$(find target/ -maxdepth 1 ! -name '*original*' -name '*.jar')
|
||||
echo Found file: $FILENAME
|
||||
|
||||
if [ $1 = 'production' ]; then
|
||||
echo Production mode
|
||||
echo $UPLOAD_KEY > upload_key
|
||||
chmod 400 upload_key
|
||||
yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/TBMC/pluginupdates
|
||||
fi
|
|
@ -69,13 +69,13 @@ public class PluginMain extends ButtonPlugin { // Translated to Java: 2015.07.15
|
|||
Component.registerComponent(this, new FunComponent());
|
||||
Component.registerComponent(this, new AppendTextComponent());
|
||||
Component.registerComponent(this, new FormatterComponent());
|
||||
getCommand2MC().registerCommand(new DebugCommand());
|
||||
getCommand2MC().registerCommand(new HelpCommand());
|
||||
getCommand2MC().registerCommand(new HistoryCommand());
|
||||
getCommand2MC().registerCommand(new InfoCommand());
|
||||
getCommand2MC().registerCommand(new MWikiCommand());
|
||||
getCommand2MC().registerCommand(new ReloadCommand());
|
||||
getCommand2MC().registerCommand(new SnapCommand());
|
||||
registerCommand(new DebugCommand());
|
||||
registerCommand(new HelpCommand());
|
||||
registerCommand(new HistoryCommand());
|
||||
registerCommand(new InfoCommand());
|
||||
registerCommand(new MWikiCommand());
|
||||
registerCommand(new ReloadCommand());
|
||||
registerCommand(new SnapCommand());
|
||||
}
|
||||
|
||||
public static Essentials essentials = null;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package buttondevteam.chat.components.chatonly;
|
||||
|
||||
import buttondevteam.chat.ChatPlayer;
|
||||
import buttondevteam.chat.PluginMain;
|
||||
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
|
||||
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
|
||||
import buttondevteam.core.ComponentManager;
|
||||
|
@ -20,7 +21,7 @@ import org.bukkit.event.player.PlayerTeleportEvent;
|
|||
* Allows players to enter chat-only mode which puts them into spectator mode and disallows moving.
|
||||
*/
|
||||
@ComponentMetadata(enabledByDefault = false)
|
||||
public class ChatOnlyComponent extends Component implements Listener {
|
||||
public class ChatOnlyComponent extends Component<PluginMain> implements Listener {
|
||||
@Override
|
||||
protected void enable() {
|
||||
registerListener(this);
|
||||
|
|
|
@ -23,7 +23,7 @@ public class SetFlairCommand extends AdminCommandBase {
|
|||
sender.sendMessage("§cPlayer not found.&r");
|
||||
return true;
|
||||
}
|
||||
short ft = 0x00;
|
||||
short ft;
|
||||
if (flairtime.equalsIgnoreCase("non-presser"))
|
||||
ft = ChatPlayer.FlairTimeNonPresser;
|
||||
else if (flairtime.equalsIgnoreCase("cant-press"))
|
||||
|
|
|
@ -6,10 +6,7 @@ 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.formatter.formatting.*;
|
||||
import buttondevteam.chat.components.fun.FunComponent;
|
||||
import buttondevteam.chat.components.towny.TownyComponent;
|
||||
import buttondevteam.chat.listener.PlayerListener;
|
||||
|
@ -19,7 +16,6 @@ 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;
|
||||
|
@ -43,73 +39,56 @@ 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 ITALIC_PATTERN_2 = 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");
|
||||
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("italic2", ITALIC_PATTERN_2).italic(true).removeCharCount((short) 1).type(ChatFormatter.Type.Range).build(),
|
||||
ChatFormatter.builder("underlined", UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 2).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)
|
||||
private static ArrayList<MatchProviderBase> commonFormatters = Lists.newArrayList(
|
||||
new RangeMatchProvider("bold", "**", FormatSettings.builder().bold(true).build()),
|
||||
new RangeMatchProvider("italic", "*", FormatSettings.builder().italic(true).build()),
|
||||
new RangeMatchProvider("underlined", "__", FormatSettings.builder().underlined(true).build()),
|
||||
new RangeMatchProvider("italic2", "_", FormatSettings.builder().italic(true).build()),
|
||||
new RangeMatchProvider("strikethrough", "~~", FormatSettings.builder().strikethrough(true).build()),
|
||||
new RangeMatchProvider("spoiler", "||", FormatSettings.builder().obfuscated(true)
|
||||
.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) -> {
|
||||
}).build()),
|
||||
new StringMatchProvider("nullMention", FormatSettings.builder().color(Color.DarkRed).build(), true, "null"), // Properly added a bug as a feature
|
||||
new StringMatchProvider("consolePing", FormatSettings.builder().color(Color.Aqua)
|
||||
.onmatch((match, builder, section) -> {
|
||||
if (!pingedconsole) {
|
||||
System.out.print("\007");
|
||||
pingedconsole = true; // Will set it to false in ProcessChat
|
||||
}
|
||||
return match;
|
||||
}).priority(Priority.High).build(),
|
||||
return "@console";
|
||||
}).build(), true, "@console"),
|
||||
|
||||
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) -> {
|
||||
new StringMatchProvider("cyan", FormatSettings.builder().color(Color.Aqua).build(), true, "cyan"), // #55
|
||||
new RangeMatchProvider("code", "`", FormatSettings.builder().color(Color.DarkGray).build()),
|
||||
new RegexMatchProvider("maskedLink", MASKED_LINK_PATTERN, FormatSettings.builder().underlined(true)
|
||||
.onmatch((match, builder, section) -> {
|
||||
String text, link;
|
||||
if (section.Matches.size() < 2 || (text = section.Matches.get(0)).length() == 0 || (link = section.Matches.get(1)).length() == 0)
|
||||
return "";
|
||||
builder.setOpenlink(link);
|
||||
return text;
|
||||
}).type(ChatFormatter.Type.Excluder).build(),
|
||||
ChatFormatter.builder("url", URL_PATTERN).underlined(true).openlink("$1").type(ChatFormatter.Type.Excluder).build(),
|
||||
ChatFormatter.builder("someone", SOMEONE_PATTERN).color(Color.Aqua).onmatch((match, builder, section) -> {
|
||||
}).build()),
|
||||
new RegexMatchProvider("url", URL_PATTERN, FormatSettings.builder().underlined(true).openlink("$1").build()),
|
||||
new RegexMatchProvider("hashtag", HASHTAG_PATTERN, FormatSettings.builder().color(Color.Blue).openlink("https://twitter.com/hashtag/$1").build()),
|
||||
new StringMatchProvider("someone", FormatSettings.builder().color(Color.Aqua)
|
||||
.onmatch((match, builder, section) -> {
|
||||
if (Bukkit.getOnlinePlayers().size() == 0) return match;
|
||||
var players = ImmutableList.copyOf(Bukkit.getOnlinePlayers());
|
||||
var playerC = new Random().nextInt(players.size());
|
||||
var player = players.get(playerC);
|
||||
playPingSound(player, ComponentManager.getIfEnabled(FormatterComponent.class));
|
||||
return "@someone (" + player.getDisplayName() + "§r)";
|
||||
}).build());
|
||||
}).build(), true, "@someone"));
|
||||
private static Gson gson = new GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum())
|
||||
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
|
||||
|
@ -164,20 +143,19 @@ public class ChatProcessing {
|
|||
colormode = Color.Green;
|
||||
// If greentext, ignore channel or player colors
|
||||
|
||||
ArrayList<ChatFormatter> formatters;
|
||||
ArrayList<MatchProviderBase> formatters;
|
||||
if (component.allowFormatting().get()) {
|
||||
formatters = addFormatters(colormode, e::shouldSendTo, component);
|
||||
formatters = addFormatters(e::shouldSendTo, component);
|
||||
if (colormode == channel.Color().get() && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
|
||||
createRPC(colormode, formatters);
|
||||
}
|
||||
pingedconsole = false; // Will set it to true onmatch (static constructor)
|
||||
} else
|
||||
formatters = Lists.newArrayList(ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN)
|
||||
.color(Color.White).priority(Priority.Low).build()); //This formatter is necessary
|
||||
formatters = Lists.newArrayList();
|
||||
|
||||
TellrawPart json = createTellraw(sender, message, player, mp, e.getUser(), channelidentifier, e.getOrigin());
|
||||
long combinetime = System.nanoTime();
|
||||
ChatFormatter.Combine(formatters, message, json, component.getConfig());
|
||||
ChatFormatter.Combine(formatters, message, json, component.getConfig(), FormatSettings.builder().color(colormode).build());
|
||||
combinetime = System.nanoTime() - combinetime;
|
||||
String jsonstr = toJson(json);
|
||||
if (jsonstr.length() >= 32767) {
|
||||
|
@ -222,12 +200,12 @@ public class ChatProcessing {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void createRPC(Color colormode, ArrayList<ChatFormatter> formatters) {
|
||||
static void createRPC(Color colormode, ArrayList<MatchProviderBase> formatters) {
|
||||
final AtomicInteger rpc = new AtomicInteger(0);
|
||||
formatters.add(ChatFormatter.builder("rpc", WORD_PATTERN).color(colormode).onmatch((match, cf, s) -> {
|
||||
formatters.add(new RegexMatchProvider("rpc", WORD_PATTERN, FormatSettings.builder().color(colormode).onmatch((match, cf, s) -> {
|
||||
cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
|
||||
return match;
|
||||
}).build());
|
||||
}).build()));
|
||||
}
|
||||
|
||||
public static String toJson(TellrawPart json) {
|
||||
|
@ -273,43 +251,21 @@ public class ChatProcessing {
|
|||
+ "]";
|
||||
}
|
||||
|
||||
static ArrayList<ChatFormatter> addFormatters(Color colormode, Predicate<Player> canSee, @Nullable FormatterComponent component) {
|
||||
static ArrayList<MatchProviderBase> addFormatters(Predicate<Player> canSee, @Nullable FormatterComponent component) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayList<ChatFormatter> formatters = (ArrayList<ChatFormatter>) commonFormatters.clone();
|
||||
|
||||
formatters.add(
|
||||
ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
|
||||
ArrayList<MatchProviderBase> formatters = (ArrayList<MatchProviderBase>) commonFormatters.clone();
|
||||
|
||||
boolean nottest; //Not assigning a default value, so that it can only be used in the if
|
||||
if ((nottest = Bukkit.getOnlinePlayers().size() > 0) || 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
|
||||
String[] names;
|
||||
if (nottest)
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (canSee.test(p)) {
|
||||
namesb.append(p.getName()).append("|");
|
||||
addNameFormatter = true;
|
||||
}
|
||||
}
|
||||
names = Bukkit.getOnlinePlayers().stream().filter(canSee).map(CommandSender::getName).toArray(String[]::new);
|
||||
else {
|
||||
for (String testPlayer : testPlayers)
|
||||
namesb.append(testPlayer).append("|");
|
||||
addNameFormatter = true;
|
||||
names = new String[testPlayers.length];
|
||||
System.arraycopy(testPlayers, 0, names, 0, testPlayers.length);
|
||||
}
|
||||
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(")");
|
||||
String[] nicknames = Bukkit.getOnlinePlayers().stream().filter(canSee).map(Player::getUniqueId).map(PlayerListener.nicknames.inverse()::get)
|
||||
.filter(Objects::nonNull).toArray(String[]::new);
|
||||
|
||||
Consumer<String> error = message -> {
|
||||
if (PluginMain.Instance != null)
|
||||
|
@ -318,8 +274,8 @@ public class ChatProcessing {
|
|||
System.out.println(message);
|
||||
};
|
||||
|
||||
if (addNameFormatter)
|
||||
formatters.add(ChatFormatter.builder("name", Pattern.compile(namesb.toString())).color(Color.Aqua)
|
||||
if (names.length > 0) //Add as first so it handles special characters (_) - though the order of the different types are defined
|
||||
formatters.add(0, new StringMatchProvider("name", FormatSettings.builder().color(Color.Aqua)
|
||||
.onmatch((match, builder, section) -> {
|
||||
Player p = Bukkit.getPlayer(match);
|
||||
Optional<String> pn = nottest ? Optional.empty()
|
||||
|
@ -334,10 +290,10 @@ public class ChatProcessing {
|
|||
}
|
||||
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());
|
||||
}).build(), true, names));
|
||||
|
||||
if (addNickFormatter)
|
||||
formatters.add(ChatFormatter.builder("nickname", Pattern.compile(nicksb.toString())).color(Color.Aqua)
|
||||
if (nicknames.length > 0) //Add as first so it handles special characters
|
||||
formatters.add(0, new StringMatchProvider("nickname", FormatSettings.builder().color(Color.Aqua)
|
||||
.onmatch((match, builder, section) -> {
|
||||
if (PlayerListener.nicknames.containsKey(match.toLowerCase())) { //Made a stream and all that but I can actually store it lowercased
|
||||
Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match.toLowerCase()));
|
||||
|
@ -352,7 +308,7 @@ public class ChatProcessing {
|
|||
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());
|
||||
}).build(), true, nicknames));
|
||||
}
|
||||
return formatters;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ChatFormatUtils {
|
||||
private ChatFormatUtils() {}
|
||||
|
||||
static void sendMessageWithPointer(String str, int... pointer) {
|
||||
DebugCommand.SendDebugMessage(str);
|
||||
StringBuilder sb = new StringBuilder(str.length());
|
||||
Arrays.sort(pointer);
|
||||
for (int i = 0; i < pointer.length; i++) {
|
||||
for (int j = 0; j < pointer[i] - (i > 0 ? pointer[i - 1] + 1 : 0); j++)
|
||||
sb.append(' ');
|
||||
if (pointer[i] == (i > 0 ? pointer[i - 1] : -1))
|
||||
continue;
|
||||
sb.append('^');
|
||||
}
|
||||
DebugCommand.SendDebugMessage(sb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given start and end position is inside any of the ranges
|
||||
*/
|
||||
static boolean isInRange(int start, int end, ArrayList<int[]> ranges) {
|
||||
return ranges.stream().anyMatch(range -> range[1] >= start && range[0] <= end);
|
||||
}
|
||||
}
|
|
@ -1,79 +1,23 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
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.Priority;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* A {@link MatchProvider} finds where the given {@link FormatSettings} need to be applied. {@link ChatFormatter#Combine(List, String, TellrawPart, IHaveConfig, FormatSettings)}} is used to turn it into a {@link TellrawPart}, combining
|
||||
* intersecting parts found, for example when {@code _abc*def*ghi_} is said in chat, it'll turn it into an underlined part, then an underlined <i>and italics</i> part, finally an underlined part
|
||||
* again.
|
||||
*
|
||||
* @author NorbiPeti
|
||||
*/
|
||||
@SuppressWarnings("UnusedAssignment")
|
||||
@Data
|
||||
@Builder
|
||||
public final class ChatFormatter {
|
||||
Pattern regex;
|
||||
boolean italic;
|
||||
boolean bold;
|
||||
boolean underlined;
|
||||
boolean strikethrough;
|
||||
boolean obfuscated;
|
||||
Color color;
|
||||
TriFunc<String, ChatFormatter, FormattedSection, String> onmatch;
|
||||
String openlink;
|
||||
@Builder.Default
|
||||
Priority priority = Priority.Normal;
|
||||
@Builder.Default
|
||||
short removeCharCount = 0;
|
||||
@Builder.Default
|
||||
Type type = Type.Normal;
|
||||
String hoverText;
|
||||
String name;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChatFormatter{" +
|
||||
"name='" + 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 {
|
||||
Normal,
|
||||
/**
|
||||
* Matches a start and an end section which gets converted to one section (for example see italics)
|
||||
*/
|
||||
Range,
|
||||
/**
|
||||
* Exclude matching area from further processing (besides this formatter)
|
||||
*/
|
||||
Excluder
|
||||
private ChatFormatter() {
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
@ -81,31 +25,32 @@ public final class ChatFormatter {
|
|||
R apply(T1 x1, T2 x2, T3 x3);
|
||||
}
|
||||
|
||||
public static void Combine(List<ChatFormatter> formatters, String str, TellrawPart tp, IHaveConfig config) {
|
||||
//synchronized: Some of the formatters are reused, see createSections(...)
|
||||
public static synchronized void Combine(List<MatchProviderBase> formatters, String str, TellrawPart tp, IHaveConfig config, FormatSettings defaults) {
|
||||
/*
|
||||
* This method assumes that there is always a global formatter
|
||||
* A global formatter is no longer needed
|
||||
*/
|
||||
header("ChatFormatter.Combine begin");
|
||||
ArrayList<FormattedSection> sections = new ArrayList<>();
|
||||
|
||||
if (config != null) //null if testing
|
||||
formatters.removeIf(cf -> !cf.enabled(config).get()); //Remove disabled formatters
|
||||
createSections(formatters, str, sections, true);
|
||||
|
||||
header("Section creation (excluders done)");
|
||||
createSections(formatters, str, sections, false);
|
||||
sortSections(sections);
|
||||
|
||||
var excluded = new ArrayList<int[]>();
|
||||
/*
|
||||
* 0: Start - 1: End index
|
||||
*/
|
||||
val remchars = new ArrayList<int[]>();
|
||||
|
||||
header("Range section conversion");
|
||||
sections = convertRangeSections(str, sections, remchars);
|
||||
escapeThings(str, excluded, remchars);
|
||||
|
||||
header("Adding remove chars (RC)"); // Important to add after the range section conversion
|
||||
addRemChars(sections, remchars, str);
|
||||
sections.add(new FormattedSection(defaults, 0, str.length() - 1, Collections.emptyList())); //Add entire message
|
||||
var providers = formatters.stream().filter(mp -> mp instanceof RegexMatchProvider).collect(Collectors.toList());
|
||||
createSections(providers, str, sections, excluded, remchars);
|
||||
providers = formatters.stream().filter(mp -> mp instanceof StringMatchProvider).collect(Collectors.toList());
|
||||
createSections(providers, str, sections, excluded, remchars);
|
||||
providers = formatters.stream().filter(mp -> mp instanceof RangeMatchProvider).collect(Collectors.toList());
|
||||
createSections(providers, str, sections, excluded, remchars);
|
||||
sortSections(sections);
|
||||
|
||||
header("Section combining");
|
||||
combineSections(str, sections);
|
||||
|
@ -115,145 +60,35 @@ public final class ChatFormatter {
|
|||
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 void escapeThings(String str, ArrayList<int[]> ignoredAreas, ArrayList<int[]> remchars) {
|
||||
boolean escaped = false;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (str.charAt(i) == '\\') {
|
||||
remchars.add(new int[]{i, i});
|
||||
ignoredAreas.add(new int[]{i + 1, i + 1});
|
||||
i++; //Ignore a potential second slash
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void newCombine(String str, ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
|
||||
var stack = new Stack<FormattedSection>();
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
for (Iterator<FormattedSection> iterator = sections.iterator(); iterator.hasNext(); ) {
|
||||
FormattedSection section = iterator.next();
|
||||
if (section.Start <= i) {
|
||||
stack.push(section);
|
||||
private static void createSections(List<MatchProviderBase> formatters, String str, ArrayList<FormattedSection> sections,
|
||||
ArrayList<int[]> excludedAreas, ArrayList<int[]> removedCharacters) {
|
||||
formatters.forEach(MatchProviderBase::reset); //Reset state information, as we aren't doing deep cloning
|
||||
while (formatters.size() > 0) {
|
||||
for (var iterator = formatters.iterator(); iterator.hasNext(); ) {
|
||||
MatchProviderBase formatter = iterator.next();
|
||||
DebugCommand.SendDebugMessage("Checking provider: " + formatter);
|
||||
var sect = formatter.getNextSection(str, excludedAreas, removedCharacters);
|
||||
if (sect != null) //Not excluding the area here because the range matcher shouldn't take it all
|
||||
sections.add(sect);
|
||||
if (formatter.isFinished()) {
|
||||
DebugCommand.SendDebugMessage("Provider finished");
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ArrayList<FormattedSection> convertRangeSections(String str, ArrayList<FormattedSection> sections, ArrayList<int[]> remchars) {
|
||||
ArrayList<FormattedSection> combined = new ArrayList<>();
|
||||
Map<ChatFormatter, FormattedSection> nextSection = new HashMap<>();
|
||||
boolean escaped = false;
|
||||
int takenStart = -1, takenEnd = -1;
|
||||
ChatFormatter takenFormatter = null;
|
||||
boolean takenByBigGuy = false; //Can't win against him (finished sections take precedence)
|
||||
for (final FormattedSection section : sections) {
|
||||
// Set ending to -1 until closed with another 1 long "section" - only do this if IsRange is true
|
||||
if (section.type != Type.Range) {
|
||||
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
|
||||
if (escaped) {// Don't add the escape character
|
||||
remchars.add(new int[]{section.Start, section.Start});
|
||||
DebugCommand.SendDebugMessage("Found escaper section: " + section);
|
||||
} else {
|
||||
combined.add(section); // The above will delete the \
|
||||
DebugCommand.SendDebugMessage("Added section: " + section);
|
||||
}
|
||||
sendMessageWithPointer(str, section.Start, section.End);
|
||||
continue;
|
||||
}
|
||||
if (!escaped) {
|
||||
ChatFormatter formatter = section.Formatters.get(0);
|
||||
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 (takenByBigGuy || formatter.removeCharCount < takenEnd - takenStart) {
|
||||
DebugCommand.SendDebugMessage("Lose: " + section);
|
||||
sendMessageWithPointer(str, section.Start, section.End);
|
||||
DebugCommand.SendDebugMessage("And win: " + takenFormatter);
|
||||
continue; // The current section loses
|
||||
}
|
||||
nextSection.remove(takenFormatter); // The current section wins
|
||||
DebugCommand.SendDebugMessage("Win: " + section);
|
||||
sendMessageWithPointer(str, section.Start, section.End);
|
||||
DebugCommand.SendDebugMessage("And lose: " + takenFormatter);
|
||||
}
|
||||
boolean hasFormatter = nextSection.containsKey(formatter);
|
||||
if (!hasFormatter) {
|
||||
val ff = formatter;
|
||||
val cfo = nextSection.keySet().stream().filter(f -> f.removeCharCount > ff.removeCharCount).findAny();
|
||||
if (cfo.isPresent()) {
|
||||
//formatter = cfo.get();
|
||||
val s = nextSection.get(cfo.get());
|
||||
int takenS = section.Start, takenE = section.Start + formatter.removeCharCount;
|
||||
if (s.Start == takenS || (s.Start > takenS && s.Start < takenE)) { //Peek()
|
||||
hasFormatter = true;
|
||||
continue; //Not the formatter we're looking for - TODO: It doesn't fix the problem of italics at the end
|
||||
}
|
||||
}
|
||||
}
|
||||
takenStart = section.Start;
|
||||
takenEnd = section.Start + formatter.removeCharCount;
|
||||
takenFormatter = formatter;
|
||||
if (hasFormatter) {
|
||||
FormattedSection s = nextSection.remove(formatter);
|
||||
//HACK? If we can find another section that removes more characters, finish that instead
|
||||
// section: the ending marker section - s: the to-be full section
|
||||
s.End = takenEnd - 1; //Take the remCharCount into account as well
|
||||
// s.IsRange = false; // IsRange means it's a 1 long section indicating a start or an end
|
||||
combined.add(s);
|
||||
takenByBigGuy = true;
|
||||
DebugCommand.SendDebugMessage("Finished section: " + s);
|
||||
sendMessageWithPointer(str, s.Start, s.End);
|
||||
} else {
|
||||
DebugCommand.SendDebugMessage("Adding next section: " + section);
|
||||
sendMessageWithPointer(str, section.Start, section.End);
|
||||
nextSection.put(formatter, section);
|
||||
takenByBigGuy = false;
|
||||
}
|
||||
DebugCommand
|
||||
.SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter);
|
||||
sendMessageWithPointer(str, takenStart, takenEnd);
|
||||
} else {
|
||||
DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character)
|
||||
sendMessageWithPointer(str, section.Start, section.End);
|
||||
escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*'
|
||||
}
|
||||
}
|
||||
//Do not finish unfinished sections, ignore them
|
||||
sections = combined;
|
||||
return sections;
|
||||
}
|
||||
|
||||
private static void addRemChars(ArrayList<FormattedSection> sections, ArrayList<int[]> remchars, String str) {
|
||||
sections.stream()
|
||||
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
|
||||
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.Start, fs.Start + rcc - 1}))
|
||||
.forEach(remchars::add);
|
||||
sections.stream()
|
||||
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
|
||||
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[]{fs.End - rcc + 1, fs.End}))
|
||||
.forEach(remchars::add);
|
||||
DebugCommand.SendDebugMessage("Added remchars:");
|
||||
DebugCommand.SendDebugMessage(remchars.stream().map(Arrays::toString).collect(Collectors.joining("; ")));
|
||||
sendMessageWithPointer(str,
|
||||
remchars.stream().flatMapToInt(Arrays::stream).toArray());
|
||||
}
|
||||
|
||||
private static void combineSections(String str, ArrayList<FormattedSection> sections) {
|
||||
for (int i = 1; i < sections.size(); i++) {
|
||||
DebugCommand.SendDebugMessage("i: " + i);
|
||||
|
@ -262,7 +97,8 @@ public final class ChatFormatter {
|
|||
{
|
||||
FormattedSection firstSect = sections.get(i - 1);
|
||||
FormattedSection lastSect = sections.get(i);
|
||||
if (firstSect.Start > lastSect.Start) { //The first can't start later
|
||||
if (firstSect.Start > lastSect.Start //The first can't start later
|
||||
|| (firstSect.Start == lastSect.Start && firstSect.End < lastSect.End)) {
|
||||
var section = firstSect;
|
||||
firstSect = lastSect;
|
||||
lastSect = section;
|
||||
|
@ -271,41 +107,40 @@ public final class ChatFormatter {
|
|||
lastSection = lastSect;
|
||||
}
|
||||
DebugCommand.SendDebugMessage("Combining sections " + firstSection);
|
||||
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||
DebugCommand.SendDebugMessage(" and " + lastSection);
|
||||
sendMessageWithPointer(str, lastSection.Start, lastSection.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, lastSection.Start, lastSection.End);
|
||||
if (firstSection.Start == lastSection.Start && firstSection.End == lastSection.End) {
|
||||
firstSection.Formatters.addAll(lastSection.Formatters);
|
||||
firstSection.Settings.copyFrom(lastSection.Settings);
|
||||
firstSection.Matches.addAll(lastSection.Matches);
|
||||
firstSection.type = lastSection.type;
|
||||
DebugCommand.SendDebugMessage("To section " + firstSection);
|
||||
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||
sections.remove(i);
|
||||
i = 0;
|
||||
sortSections(sections);
|
||||
continue;
|
||||
} else if (firstSection.End > lastSection.Start && firstSection.Start < lastSection.End) {
|
||||
int origend2 = firstSection.End;
|
||||
} else if (firstSection.End >= lastSection.Start && firstSection.Start <= lastSection.End) {
|
||||
int firstSectEnd = firstSection.End;
|
||||
firstSection.End = lastSection.Start - 1;
|
||||
int origend = lastSection.End;
|
||||
FormattedSection section = new FormattedSection(firstSection.Formatters, lastSection.Start, origend,
|
||||
firstSection.Matches, Type.Normal);
|
||||
section.Formatters.addAll(lastSection.Formatters);
|
||||
section.Matches.addAll(lastSection.Matches); // TODO: Clean
|
||||
int lastSectEnd = lastSection.End;
|
||||
FormattedSection section = new FormattedSection(firstSection.Settings, lastSection.Start, lastSectEnd,
|
||||
firstSection.Matches);
|
||||
section.Settings.copyFrom(lastSection.Settings);
|
||||
section.Matches.addAll(lastSection.Matches);
|
||||
sections.add(i, section);
|
||||
// Use the properties of the first section not the second one
|
||||
lastSection.Formatters.clear();
|
||||
lastSection.Formatters.addAll(firstSection.Formatters);
|
||||
lastSection.Matches.clear();
|
||||
lastSection.Matches.addAll(firstSection.Matches);
|
||||
|
||||
lastSection.Start = origend + 1;
|
||||
lastSection.End = origend2;
|
||||
if (firstSectEnd > lastSection.End) { //Copy first section info to last as the lastSection initially cuts the firstSection in half
|
||||
lastSection.Settings = FormatSettings.builder().build();
|
||||
lastSection.Settings.copyFrom(firstSection.Settings);
|
||||
}
|
||||
|
||||
lastSection.Start = lastSectEnd + 1;
|
||||
lastSection.End = firstSectEnd;
|
||||
|
||||
Predicate<FormattedSection> removeIfNeeded = s -> {
|
||||
if (s.Start < 0 || s.End < 0 || s.Start > s.End) {
|
||||
DebugCommand.SendDebugMessage(" Removed: " + s);
|
||||
sendMessageWithPointer(str, s.Start, s.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, s.Start, s.End);
|
||||
sections.remove(s);
|
||||
return true;
|
||||
}
|
||||
|
@ -315,15 +150,15 @@ public final class ChatFormatter {
|
|||
DebugCommand.SendDebugMessage("To sections");
|
||||
if (!removeIfNeeded.test(firstSection)) {
|
||||
DebugCommand.SendDebugMessage(" 1:" + firstSection + "");
|
||||
sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, firstSection.Start, firstSection.End);
|
||||
}
|
||||
if (!removeIfNeeded.test(section)) {
|
||||
DebugCommand.SendDebugMessage(" 2:" + section + "");
|
||||
sendMessageWithPointer(str, section.Start, section.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, section.Start, section.End);
|
||||
}
|
||||
if (!removeIfNeeded.test(lastSection)) {
|
||||
DebugCommand.SendDebugMessage(" 3:" + lastSection);
|
||||
sendMessageWithPointer(str, lastSection.Start, lastSection.End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, lastSection.Start, lastSection.End);
|
||||
}
|
||||
i = 0;
|
||||
}
|
||||
|
@ -332,7 +167,7 @@ public final class ChatFormatter {
|
|||
for (int j = i - 1; j <= i + 1; j++) {
|
||||
if (j < sections.size() && sections.get(j).End < sections.get(j).Start) {
|
||||
DebugCommand.SendDebugMessage("Removing section: " + sections.get(j));
|
||||
sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End);
|
||||
sections.remove(j);
|
||||
j--;
|
||||
i = 0;
|
||||
|
@ -349,7 +184,7 @@ public final class ChatFormatter {
|
|||
String originaltext;
|
||||
int start = section.Start, end = section.End;
|
||||
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
|
||||
sendMessageWithPointer(str, start, end);
|
||||
ChatFormatUtils.sendMessageWithPointer(str, start, end);
|
||||
/*DebugCommand.SendDebugMessage("RCS: "+remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).count());
|
||||
DebugCommand.SendDebugMessage("RCE: "+remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).count());
|
||||
DebugCommand.SendDebugMessage("RCI: "+remchars.stream().filter(rc -> start < rc[0] || rc[1] < end).count());*/
|
||||
|
@ -377,29 +212,28 @@ public final class ChatFormatter {
|
|||
}
|
||||
DebugCommand.SendDebugMessage("Section text: " + originaltext);
|
||||
String openlink = null;
|
||||
section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
|
||||
//section.Formatters.sort(Comparator.comparing(cf2 -> cf2.priority.GetValue())); //Apply the highest last, to overwrite previous ones
|
||||
TellrawPart newtp = new TellrawPart("");
|
||||
for (ChatFormatter formatter : section.Formatters) {
|
||||
DebugCommand.SendDebugMessage("Applying formatter: " + formatter);
|
||||
if (formatter.onmatch != null)
|
||||
originaltext = formatter.onmatch.apply(originaltext, formatter, section);
|
||||
if (formatter.color != null)
|
||||
newtp.setColor(formatter.color);
|
||||
if (formatter.bold)
|
||||
var settings = section.Settings;
|
||||
DebugCommand.SendDebugMessage("Applying settings: " + settings);
|
||||
if (settings.onmatch != null)
|
||||
originaltext = settings.onmatch.apply(originaltext, settings, section);
|
||||
if (settings.color != null)
|
||||
newtp.setColor(settings.color);
|
||||
if (settings.bold)
|
||||
newtp.setBold(true);
|
||||
if (formatter.italic)
|
||||
if (settings.italic)
|
||||
newtp.setItalic(true);
|
||||
if (formatter.underlined)
|
||||
if (settings.underlined)
|
||||
newtp.setUnderlined(true);
|
||||
if (formatter.strikethrough)
|
||||
if (settings.strikethrough)
|
||||
newtp.setStrikethrough(true);
|
||||
if (formatter.obfuscated)
|
||||
if (settings.obfuscated)
|
||||
newtp.setObfuscated(true);
|
||||
if (formatter.openlink != null)
|
||||
openlink = formatter.openlink;
|
||||
if (formatter.hoverText != null)
|
||||
newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, formatter.hoverText));
|
||||
}
|
||||
if (settings.openlink != null)
|
||||
openlink = settings.openlink;
|
||||
if (settings.hoverText != null)
|
||||
newtp.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, settings.hoverText));
|
||||
if (lasttp != null && newtp.getColor() == lasttp.getColor()
|
||||
&& newtp.isBold() == lasttp.isBold()
|
||||
&& newtp.isItalic() == lasttp.isItalic()
|
||||
|
@ -427,25 +261,10 @@ public final class ChatFormatter {
|
|||
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(s1.End, s2.End)
|
||||
? s1.End == s2.End ? 0 : Integer.compare(s1.End, s2.End)
|
||||
: Integer.compare(s1.Start, s2.Start));
|
||||
}
|
||||
|
||||
private static void sendMessageWithPointer(String str, int... pointer) {
|
||||
DebugCommand.SendDebugMessage(str);
|
||||
StringBuilder sb = new StringBuilder(str.length());
|
||||
Arrays.sort(pointer);
|
||||
for (int i = 0; i < pointer.length; i++) {
|
||||
for (int j = 0; j < pointer[i] - (i > 0 ? pointer[i - 1] + 1 : 0); j++)
|
||||
sb.append(' ');
|
||||
if (pointer[i] == (i > 0 ? pointer[i - 1] : -1))
|
||||
continue;
|
||||
sb.append('^');
|
||||
}
|
||||
DebugCommand.SendDebugMessage(sb.toString());
|
||||
}
|
||||
|
||||
private static void header(String message) {
|
||||
DebugCommand.SendDebugMessage("\n--------\n" + message + "\n--------\n");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import buttondevteam.lib.chat.Color;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Describes how a matched section of the message should look. May be combined with other format settings.
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class FormatSettings {
|
||||
boolean italic;
|
||||
boolean bold;
|
||||
boolean underlined;
|
||||
boolean strikethrough;
|
||||
boolean obfuscated;
|
||||
Color color;
|
||||
ChatFormatter.TriFunc<String, FormatSettings, FormattedSection, String> onmatch;
|
||||
String openlink;
|
||||
String hoverText;
|
||||
|
||||
public void copyFrom(FormatSettings settings) {
|
||||
try {
|
||||
for (var field : FormatSettings.class.getDeclaredFields()) {
|
||||
if (field.getType() == boolean.class) {
|
||||
if (field.getBoolean(settings))
|
||||
field.setBoolean(this, true); //Set to true if either of them are true
|
||||
} else if (field.get(settings) != null) {
|
||||
//System.out.println("Setting " + field.getType() + " " + field.getName() + " from " + field.get(this) + " to " + field.get(settings));
|
||||
field.set(this, field.get(settings));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,22 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ToString
|
||||
public class FormattedSection {
|
||||
public int Start;
|
||||
public int End;
|
||||
public ArrayList<ChatFormatter> Formatters = new ArrayList<ChatFormatter>();
|
||||
public ArrayList<String> Matches = new ArrayList<String>();
|
||||
public ChatFormatter.Type type;
|
||||
public FormatSettings Settings;
|
||||
public List<String> Matches = new ArrayList<>();
|
||||
|
||||
FormattedSection(ChatFormatter formatter, int start, int end, ArrayList<String> matches, ChatFormatter.Type type) {
|
||||
FormattedSection(FormatSettings settings, int start, int end, List<String> matches) {
|
||||
Start = start;
|
||||
End = end;
|
||||
Formatters.add(formatter);
|
||||
Settings = FormatSettings.builder().build();
|
||||
Settings.copyFrom(settings);
|
||||
Matches.addAll(matches);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
FormattedSection(Collection<ChatFormatter> formatters, int start, int end, ArrayList<String> matches,
|
||||
ChatFormatter.Type type) {
|
||||
Start = start;
|
||||
End = end;
|
||||
Formatters.addAll(formatters);
|
||||
Matches.addAll(matches);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Section(" + Start + ", " + End + ", formatters: " +
|
||||
Formatters.toString() + ", matches: " + Matches.toString() + ", " +
|
||||
type + ")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Attempts to find a match for the provided message, returning null if none was found.
|
||||
*/
|
||||
public interface MatchProvider {
|
||||
@Nullable
|
||||
FormattedSection getNextSection(String message, ArrayList<int[]> ignoredAreas, ArrayList<int[]> removedCharacters);
|
||||
|
||||
boolean isFinished();
|
||||
|
||||
String getName();
|
||||
|
||||
@Override
|
||||
String toString();
|
||||
|
||||
void reset();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.architecture.IHaveConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class MatchProviderBase implements MatchProvider {
|
||||
@Getter
|
||||
protected boolean finished;
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public abstract FormattedSection getNextSection(String message, ArrayList<int[]> ignoredAreas, ArrayList<int[]> removedCharacters);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
protected abstract void resetSubclass();
|
||||
|
||||
public void reset() {
|
||||
finished = false;
|
||||
resetSubclass();
|
||||
}
|
||||
|
||||
ConfigData<Boolean> enabled(IHaveConfig config) {
|
||||
return config.getData(name + ".enabled", true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public class RangeMatchProvider extends MatchProviderBase {
|
||||
private final String pattern;
|
||||
@ToString.Exclude
|
||||
private final FormatSettings settings;
|
||||
private int nextIndex = 0;
|
||||
private FormattedSection startedSection;
|
||||
|
||||
public RangeMatchProvider(String name, String pattern, FormatSettings settings) {
|
||||
super(name);
|
||||
this.pattern = pattern;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormattedSection getNextSection(String message, ArrayList<int[]> ignoredAreas, ArrayList<int[]> removedCharacters) {
|
||||
int i, len;
|
||||
i = message.indexOf(pattern, nextIndex);
|
||||
len = pattern.length();
|
||||
nextIndex = i + len; //Set for the next method call
|
||||
if (i == -1) {
|
||||
finished = true; //Won't find any more - unfinished sections will be garbage collected
|
||||
return null;
|
||||
}
|
||||
if (ChatFormatUtils.isInRange(i, i + len - 1, ignoredAreas)) {
|
||||
DebugCommand.SendDebugMessage("Range start is in ignored area, skipping");
|
||||
return null; //Not setting finished to true, so it will go to the next match
|
||||
}
|
||||
ignoredAreas.add(new int[]{i, i + len - 1});
|
||||
if (startedSection == null) {
|
||||
DebugCommand.SendDebugMessage("Started range match from " + i + " to " + (i + len - 1));
|
||||
DebugCommand.SendDebugMessage("With settings: " + settings);
|
||||
ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1);
|
||||
startedSection = new FormattedSection(settings, i, i + len - 1, Collections.emptyList());
|
||||
return null;
|
||||
} else {
|
||||
var section = startedSection;
|
||||
DebugCommand.SendDebugMessage("Finished range match from " + section.Start + " to " + (i + len - 1));
|
||||
DebugCommand.SendDebugMessage("With settings: " + settings);
|
||||
ChatFormatUtils.sendMessageWithPointer(message, section.Start, i + len - 1);
|
||||
section.End = i + len - 1;
|
||||
removedCharacters.add(new int[]{section.Start, section.Start + len - 1});
|
||||
removedCharacters.add(new int[]{i, i + len - 1});
|
||||
startedSection = null; //Reset so next find creates a new one
|
||||
return section;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetSubclass() {
|
||||
nextIndex = 0;
|
||||
startedSection = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class RegexMatchProvider extends MatchProviderBase {
|
||||
private final Pattern pattern;
|
||||
@ToString.Exclude
|
||||
private final FormatSettings settings;
|
||||
private Matcher matcher;
|
||||
|
||||
public RegexMatchProvider(String name, Pattern pattern, FormatSettings settings) {
|
||||
super(name);
|
||||
this.pattern = pattern;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FormattedSection getNextSection(String message, ArrayList<int[]> ignoredAreas, ArrayList<int[]> removedCharacters) {
|
||||
if (matcher == null)
|
||||
matcher = pattern.matcher(message);
|
||||
if (!matcher.find()) {
|
||||
finished = true;
|
||||
return null;
|
||||
}
|
||||
int start = matcher.start(), end = matcher.end() - 1;
|
||||
DebugCommand.SendDebugMessage("Found regex match from " + start + " to " + end);
|
||||
DebugCommand.SendDebugMessage("With settings: " + settings);
|
||||
ChatFormatUtils.sendMessageWithPointer(message, start, end);
|
||||
if (ChatFormatUtils.isInRange(start, end, ignoredAreas)) {
|
||||
DebugCommand.SendDebugMessage("Match is in ignored area, skipping");
|
||||
return null; //Not setting finished to true, so it will go to the next match
|
||||
}
|
||||
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));
|
||||
ignoredAreas.add(new int[]{start, end});
|
||||
return new FormattedSection(settings, matcher.start(), matcher.end() - 1, groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetSubclass() {
|
||||
matcher = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package buttondevteam.chat.components.formatter.formatting;
|
||||
|
||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public class StringMatchProvider extends MatchProviderBase {
|
||||
private final String[] strings;
|
||||
@ToString.Exclude
|
||||
private final FormatSettings settings;
|
||||
private int nextIndex = 0;
|
||||
private boolean ignoreCase;
|
||||
|
||||
/**
|
||||
* Matches the given strings in the order given
|
||||
*
|
||||
* @param settings The format settings
|
||||
* @param strings The strings to match in the correct order
|
||||
*/
|
||||
public StringMatchProvider(String name, FormatSettings settings, boolean ignoreCase, String... strings) {
|
||||
super(name);
|
||||
this.settings = settings;
|
||||
this.strings = strings;
|
||||
this.ignoreCase = ignoreCase;
|
||||
if (ignoreCase) {
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
strings[i] = strings[i].toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FormattedSection getNextSection(String message, ArrayList<int[]> ignoredAreas, ArrayList<int[]> removedCharacters) {
|
||||
if (ignoreCase)
|
||||
message = message.toLowerCase();
|
||||
int i = -1, len = 0;
|
||||
for (String string : strings) {
|
||||
i = message.indexOf(string, nextIndex);
|
||||
len = string.length();
|
||||
if (i != -1) break;
|
||||
}
|
||||
if (i == -1) {
|
||||
finished = true; //Won't find any more
|
||||
return null;
|
||||
}
|
||||
nextIndex = i + len;
|
||||
if (ChatFormatUtils.isInRange(i, i + len - 1, ignoredAreas)) {
|
||||
DebugCommand.SendDebugMessage("String is in ignored area, skipping");
|
||||
return null; //Not setting finished to true, so it will go to the next match
|
||||
}
|
||||
DebugCommand.SendDebugMessage("Found string match from " + i + " to " + (i + len - 1));
|
||||
DebugCommand.SendDebugMessage("With settings: " + settings);
|
||||
ChatFormatUtils.sendMessageWithPointer(message, i, i + len - 1);
|
||||
ignoredAreas.add(new int[]{i, i + len - 1});
|
||||
return new FormattedSection(settings, i, i + len - 1, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetSubclass() {
|
||||
nextIndex = 0;
|
||||
}
|
||||
}
|
|
@ -71,6 +71,6 @@ public final class TellrawEvent<T extends TellrawEvent.Action> implements Serial
|
|||
}
|
||||
}
|
||||
|
||||
public static interface Action extends TellrawSerializableEnum {
|
||||
public interface Action extends TellrawSerializableEnum {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public abstract class TellrawSerializer {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void write(JsonWriter writer, Boolean val) throws IOException {
|
||||
if (val)
|
||||
|
|
|
@ -12,8 +12,6 @@ import lombok.RequiredArgsConstructor;
|
|||
import lombok.val;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@CommandClass(helpText = {
|
||||
"Town Color", //
|
||||
"This command allows setting a color for a town.", //
|
||||
|
@ -23,18 +21,6 @@ import java.lang.reflect.Method;
|
|||
@RequiredArgsConstructor
|
||||
public class TownColorCommand extends UCommandBase {
|
||||
private final TownColorComponent component;
|
||||
@Override
|
||||
public String[] getHelpText(Method method, Command2.Subcommand ann) {
|
||||
StringBuilder cns = new StringBuilder(" <colorname1>");
|
||||
for (int i = 2; i <= component.colorCount().get(); i++)
|
||||
cns.append(" [colorname").append(i).append("]");
|
||||
return new String[] { //
|
||||
"§6---- Town Color ----", //
|
||||
"This command allows setting color(s) for a town.", //
|
||||
"The town will be shown with this color on Dynmap and all players in the town will appear in chat with these colors.", //
|
||||
"The colors will split the name evenly.", //
|
||||
};
|
||||
}
|
||||
|
||||
@Command2.Subcommand
|
||||
public boolean def(Player player, String... colornames) {
|
||||
|
|
|
@ -19,14 +19,12 @@ import lombok.val;
|
|||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.dynmap.towny.DTBridge;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.BiFunction;
|
||||
|
@ -81,14 +79,10 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
|
|||
var cs = getConfig().getConfig().getConfigurationSection("towncolors");
|
||||
if (cs != null)
|
||||
loadTC.accept(cs);
|
||||
else
|
||||
load_old(loadTC, null); //Load old data
|
||||
if (usenc) {
|
||||
var ncs = getConfig().getConfig().getConfigurationSection("nationcolors");
|
||||
if (ncs != null)
|
||||
loadNC.accept(ncs);
|
||||
else
|
||||
load_old(null, loadNC); //Why not choose by making different args null
|
||||
}
|
||||
|
||||
TownColors.keySet().removeIf(t -> !TownyComponent.TU.getTownsMap().containsKey(t)); // Removes town colors for deleted/renamed towns
|
||||
|
@ -227,25 +221,4 @@ public class TownColorComponent extends Component<PluginMain> implements Listene
|
|||
public void onPlayerJoin(TBMCPlayerJoinEvent event) {
|
||||
updatePlayerColors(event.getPlayer(), event.GetPlayer().asPluginPlayer(ChatPlayer.class));
|
||||
}
|
||||
|
||||
private static void load_old(Consumer<ConfigurationSection> loadTC,
|
||||
Consumer<ConfigurationSection> loadNC) {
|
||||
PluginMain.Instance.getLogger().info("Loading files...");
|
||||
try {
|
||||
File file = new File("TBMC/chatsettings.yml");
|
||||
if (file.exists()) {
|
||||
YamlConfiguration yc = new YamlConfiguration();
|
||||
yc.load(file);
|
||||
ConfigurationSection cs;
|
||||
if (loadTC != null && (cs = yc.getConfigurationSection("towncolors")) != null)
|
||||
loadTC.accept(cs);
|
||||
if (loadNC != null && (cs = yc.getConfigurationSection("nationcolors")) != null)
|
||||
loadNC.accept(cs);
|
||||
PluginMain.Instance.getLogger().info("Loaded files!");
|
||||
} else
|
||||
PluginMain.Instance.getLogger().info("No files to load, first run probably.");
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while loading chat files!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: Chroma-Chat
|
||||
main: buttondevteam.chat.PluginMain
|
||||
version: 4.0
|
||||
version: '4.0'
|
||||
commands:
|
||||
u:
|
||||
description: Auto-flair system. Accept or ignore flair.
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
package buttondevteam.chat;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.runner.Runner;
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
@ -20,6 +10,12 @@ import org.junit.runners.model.InitializationError;
|
|||
import org.junit.runners.model.Statement;
|
||||
import org.junit.runners.model.TestClass;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Based on {@link Parameterized}
|
||||
*
|
||||
|
@ -32,10 +28,10 @@ public class ObjectTestRunner extends Suite {
|
|||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public static @interface Objects {
|
||||
public @interface Objects {
|
||||
}
|
||||
|
||||
private class TestClassRunnerForObjects extends BlockJUnit4ClassRunner {
|
||||
private static class TestClassRunnerForObjects extends BlockJUnit4ClassRunner {
|
||||
|
||||
private List<Object> objectList;
|
||||
private int fParameterSetNumber;
|
||||
|
@ -77,13 +73,13 @@ public class ObjectTestRunner extends Suite {
|
|||
}
|
||||
}
|
||||
|
||||
private final ArrayList<Runner> runners = new ArrayList<Runner>();
|
||||
private final ArrayList<Runner> runners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Only called reflectively. Do not use programmatically.
|
||||
*/
|
||||
public ObjectTestRunner(Class<?> klass) throws Throwable {
|
||||
super(klass, Collections.<Runner>emptyList());
|
||||
super(klass, Collections.emptyList());
|
||||
List<Object> objectsList = getObjectsList(getTestClass());
|
||||
for (int i = 0; i < objectsList.size(); i++)
|
||||
runners.add(new TestClassRunnerForObjects(getTestClass().getJavaClass(), objectsList, i));
|
||||
|
|
|
@ -5,11 +5,9 @@ import buttondevteam.chat.ObjectTestRunner;
|
|||
import buttondevteam.chat.ObjectTestRunner.Objects;
|
||||
import buttondevteam.chat.PluginMain;
|
||||
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
|
||||
import buttondevteam.chat.components.formatter.formatting.ChatFormatter;
|
||||
import buttondevteam.chat.components.formatter.formatting.TellrawEvent;
|
||||
import buttondevteam.chat.components.formatter.formatting.*;
|
||||
import buttondevteam.chat.components.formatter.formatting.TellrawEvent.ClickAction;
|
||||
import buttondevteam.chat.components.formatter.formatting.TellrawEvent.HoverAction;
|
||||
import buttondevteam.chat.components.formatter.formatting.TellrawPart;
|
||||
import buttondevteam.core.TestPrepare;
|
||||
import buttondevteam.core.component.channel.Channel;
|
||||
import buttondevteam.lib.chat.Color;
|
||||
|
@ -32,7 +30,7 @@ public class ChatFormatIT {
|
|||
DebugCommand.DebugMode = true;
|
||||
PluginMain.permission = Mockito.mock(Permission.class);
|
||||
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
List<Object> list = new ArrayList<>();
|
||||
|
||||
list.add(new ChatFormatIT(sender, "*test*", new TellrawPart("test").setItalic(true).setColor(Color.White)));
|
||||
list.add(new ChatFormatIT(sender, "**test**", new TellrawPart("test").setBold(true).setColor(Color.White)));
|
||||
|
@ -64,7 +62,7 @@ public class ChatFormatIT {
|
|||
list.add(new ChatFormatIT(sender, "*https://norbipeti.github.io/ heh*", new TellrawPart("https://norbipeti.github.io/").setItalic(true).setUnderlined(true)
|
||||
.setHoverEvent(TellrawEvent.create(HoverAction.SHOW_TEXT,
|
||||
new TellrawPart("Click to open").setColor(Color.Blue)))
|
||||
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")), new TellrawPart(" heh").setItalic(true)));
|
||||
.setClickEvent(TellrawEvent.create(ClickAction.OPEN_URL, "https://norbipeti.github.io/")).setColor(Color.White), new TellrawPart(" heh").setItalic(true).setColor(Color.White)));
|
||||
list.add(new ChatFormatIT(sender, "*test _test_ test*", new TellrawPart("test test test").setItalic(true).setColor(Color.White)));
|
||||
list.add(new ChatFormatIT(sender, "*test __test__ test*", new TellrawPart("test ").setItalic(true).setColor(Color.White),
|
||||
new TellrawPart("test").setItalic(true).setUnderlined(true).setColor(Color.White), new TellrawPart(" test").setItalic(true).setColor(Color.White)));
|
||||
|
@ -109,12 +107,12 @@ public class ChatFormatIT {
|
|||
|
||||
@Test
|
||||
public void testMessage() {
|
||||
ArrayList<ChatFormatter> cfs = ChatProcessing.addFormatters(Color.White, p -> true, null);
|
||||
ArrayList<MatchProviderBase> cfs = ChatProcessing.addFormatters(p -> true, null);
|
||||
final String chid = ChatProcessing.getChannelID(Channel.GlobalChat, ChatUtils.MCORIGIN);
|
||||
if (rainbowMode)
|
||||
ChatProcessing.createRPC(Color.White, cfs);
|
||||
final TellrawPart tp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
|
||||
ChatFormatter.Combine(cfs, message, tp, null);
|
||||
ChatFormatter.Combine(cfs, message, tp, null, FormatSettings.builder().color(Color.White).build());
|
||||
System.out.println("Testing: " + message);
|
||||
// System.out.println(ChatProcessing.toJson(tp));
|
||||
final TellrawPart expectedtp = ChatProcessing.createTellraw(sender, message, null, null, null, chid, ChatUtils.MCORIGIN);
|
||||
|
|
Loading…
Reference in a new issue