diff --git a/.gitignore b/.gitignore index 456756d..a84274b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,224 +1,221 @@ -################# -## Eclipse -################# - -*.pydevproject -.metadata/ -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings/ -.loadpath -target/ -.project - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# CDT-specific -.cproject - -# PDT-specific -.buildpath - - -################# -## Visual Studio -################# - -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.sln.docstates - -# Build results - -[Dd]ebug/ -[Rr]elease/ -x64/ -build/ -[Bb]in/ -[Oo]bj/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -*_i.c -*_p.c -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.log -*.scc - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -*.ncrunch* -.*crunch*.local.xml - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.Publish.xml -*.pubxml -*.publishproj - -# NuGet Packages Directory -## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line -#packages/ - -# Windows Azure Build Output -csx -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -sql/ -*.Cache -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.[Pp]ublish.xml -*.pfx -*.publishsettings - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -App_Data/*.mdf -App_Data/*.ldf - -############# -## Windows detritus -############# - -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Mac crap -.DS_Store - - -############# -## Python -############# - -*.py[cod] - -# Packages -*.egg -*.egg-info -dist/ -build/ -eggs/ -parts/ -var/ -sdist/ -develop-eggs/ -.installed.cfg - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox - -#Translations -*.mo - -#Mr Developer -.mr.developer.cfg -.metadata/* -TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar -#*.iml -*.name -.idea/compiler.xml -*.xml -/.apt_generated/ +################# +## Eclipse +################# + +*.pydevproject +.metadata/ +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath +target/ +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.publishproj + +# NuGet Packages Directory +## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[cod] + +# Packages +*.egg +*.egg-info +dist/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg +.metadata/* +TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar +*.iml +*.name +.idea/compiler.xml +*.xml +/.apt_generated/ diff --git a/.idea/ButtonChat.iml b/.idea/ButtonChat.iml index dec5138..e69de29 100644 --- a/.idea/ButtonChat.iml +++ b/.idea/ButtonChat.iml @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 1d962ae..a3dfe4a 100644 --- a/.travis.yml +++ b/.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 diff --git a/Mvn.txt b/Mvn.txt deleted file mode 100644 index 8e9f41f..0000000 --- a/Mvn.txt +++ /dev/null @@ -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 diff --git a/ci/settings.xml b/ci/settings.xml new file mode 100644 index 0000000..a0cab53 --- /dev/null +++ b/ci/settings.xml @@ -0,0 +1,36 @@ + + + + github + + + + + github + + + + github + GitHub Towny Apache Maven Packages + https://maven.pkg.github.com/TownyAdvanced/Towny + + + + + + + + github + NorbiPeti + ${env.GHTOKEN} + + + diff --git a/deploy.sh b/deploy.sh deleted file mode 100644 index 82c8e92..0000000 --- a/deploy.sh +++ /dev/null @@ -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 diff --git a/src/main/java/buttondevteam/chat/PluginMain.java b/src/main/java/buttondevteam/chat/PluginMain.java index 6e0f929..acfd694 100644 --- a/src/main/java/buttondevteam/chat/PluginMain.java +++ b/src/main/java/buttondevteam/chat/PluginMain.java @@ -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; diff --git a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java index ecf0ce1..18147c8 100644 --- a/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java +++ b/src/main/java/buttondevteam/chat/components/chatonly/ChatOnlyComponent.java @@ -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 implements Listener { @Override protected void enable() { registerListener(this); diff --git a/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java b/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java index 36d9275..575d57f 100644 --- a/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java +++ b/src/main/java/buttondevteam/chat/components/flair/SetFlairCommand.java @@ -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")) diff --git a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java index 4e48b8f..d97d289 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java +++ b/src/main/java/buttondevteam/chat/components/formatter/ChatProcessing.java @@ -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 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 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) -> { - if (!pingedconsole) { - System.out.print("\007"); - pingedconsole = true; // Will set it to false in ProcessChat - } - return match; - }).priority(Priority.High).build(), + }).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 "@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) -> { - 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) -> { - 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()); + 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; + }).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(), 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 formatters; + ArrayList 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 formatters) { + static void createRPC(Color colormode, ArrayList 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 addFormatters(Color colormode, Predicate canSee, @Nullable FormatterComponent component) { + static ArrayList addFormatters(Predicate canSee, @Nullable FormatterComponent component) { @SuppressWarnings("unchecked") - ArrayList formatters = (ArrayList) commonFormatters.clone(); - - formatters.add( - ChatFormatter.builder("entireMessage", ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build()); + ArrayList formatters = (ArrayList) 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 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 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; } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java new file mode 100644 index 0000000..e9f41d2 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatUtils.java @@ -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 ranges) { + return ranges.stream().anyMatch(range -> range[1] >= start && range[0] <= end); + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java index 14294f3..bee0798 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/ChatFormatter.java @@ -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 and italics 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 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 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 formatters, String str, TellrawPart tp, IHaveConfig config) { + //synchronized: Some of the formatters are reused, see createSections(...) + public static synchronized void Combine(List 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 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(); /* * 0: Start - 1: End index */ val remchars = new ArrayList(); - 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 formatters, String str, ArrayList 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 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 ignoredAreas, ArrayList 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 sections, ArrayList remchars) { - var stack = new Stack(); - for (int i = 0; i < str.length(); i++) { - for (Iterator iterator = sections.iterator(); iterator.hasNext(); ) { - FormattedSection section = iterator.next(); - if (section.Start <= i) { - stack.push(section); + private static void createSections(List formatters, String str, ArrayList sections, + ArrayList excludedAreas, ArrayList 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 convertRangeSections(String str, ArrayList sections, ArrayList remchars) { - ArrayList combined = new ArrayList<>(); - Map 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 sections, ArrayList 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 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 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) - newtp.setBold(true); - if (formatter.italic) - newtp.setItalic(true); - if (formatter.underlined) - newtp.setUnderlined(true); - if (formatter.strikethrough) - newtp.setStrikethrough(true); - if (formatter.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)); - } + 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 (settings.italic) + newtp.setItalic(true); + if (settings.underlined) + newtp.setUnderlined(true); + if (settings.strikethrough) + newtp.setStrikethrough(true); + if (settings.obfuscated) + newtp.setObfuscated(true); + 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 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"); } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java new file mode 100644 index 0000000..e0bfa4c --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormatSettings.java @@ -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 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(); + } + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java index c609e58..eab4575 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/FormattedSection.java @@ -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 Formatters = new ArrayList(); - public ArrayList Matches = new ArrayList(); - public ChatFormatter.Type type; + public FormatSettings Settings; + public List Matches = new ArrayList<>(); - FormattedSection(ChatFormatter formatter, int start, int end, ArrayList matches, ChatFormatter.Type type) { + FormattedSection(FormatSettings settings, int start, int end, List matches) { Start = start; End = end; - Formatters.add(formatter); + Settings = FormatSettings.builder().build(); + Settings.copyFrom(settings); Matches.addAll(matches); - this.type = type; - } - - FormattedSection(Collection formatters, int start, int end, ArrayList 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 + ")"; } } \ No newline at end of file diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java new file mode 100644 index 0000000..c1d2d46 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProvider.java @@ -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 ignoredAreas, ArrayList removedCharacters); + + boolean isFinished(); + + String getName(); + + @Override + String toString(); + + void reset(); +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java new file mode 100644 index 0000000..fd25901 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/MatchProviderBase.java @@ -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 ignoredAreas, ArrayList removedCharacters); + + @Override + public String toString() { + return name; + } + + protected abstract void resetSubclass(); + + public void reset() { + finished = false; + resetSubclass(); + } + + ConfigData enabled(IHaveConfig config) { + return config.getData(name + ".enabled", true); + } + +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java new file mode 100644 index 0000000..aa872cb --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RangeMatchProvider.java @@ -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 ignoredAreas, ArrayList 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; + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java new file mode 100644 index 0000000..c64ddc9 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/RegexMatchProvider.java @@ -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 ignoredAreas, ArrayList 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 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; + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java new file mode 100644 index 0000000..a9a1184 --- /dev/null +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/StringMatchProvider.java @@ -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 ignoredAreas, ArrayList 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; + } +} diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java index 4c532e5..53fe988 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawEvent.java @@ -71,6 +71,6 @@ public final class TellrawEvent implements Serial } } - public static interface Action extends TellrawSerializableEnum { + public interface Action extends TellrawSerializableEnum { } } diff --git a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java index b1a36fd..4f9c450 100644 --- a/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java +++ b/src/main/java/buttondevteam/chat/components/formatter/formatting/TellrawSerializer.java @@ -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) diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java index 0bfdcd6..8dd911c 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorCommand.java @@ -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(" "); - 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) { diff --git a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java index d6d0886..7c50ebd 100644 --- a/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java +++ b/src/main/java/buttondevteam/chat/components/towncolors/TownColorComponent.java @@ -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 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 implements Listene public void onPlayerJoin(TBMCPlayerJoinEvent event) { updatePlayerColors(event.getPlayer(), event.GetPlayer().asPluginPlayer(ChatPlayer.class)); } - - private static void load_old(Consumer loadTC, - Consumer 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); - } - } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 20f270a..5eefc33 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -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. diff --git a/src/test/java/buttondevteam/chat/ObjectTestRunner.java b/src/test/java/buttondevteam/chat/ObjectTestRunner.java index 25785ee..1b5a034 100644 --- a/src/test/java/buttondevteam/chat/ObjectTestRunner.java +++ b/src/test/java/buttondevteam/chat/ObjectTestRunner.java @@ -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 objectList; private int fParameterSetNumber; @@ -77,13 +73,13 @@ public class ObjectTestRunner extends Suite { } } - private final ArrayList runners = new ArrayList(); + private final ArrayList runners = new ArrayList<>(); /** * Only called reflectively. Do not use programmatically. */ public ObjectTestRunner(Class klass) throws Throwable { - super(klass, Collections.emptyList()); + super(klass, Collections.emptyList()); List objectsList = getObjectsList(getTestClass()); for (int i = 0; i < objectsList.size(); i++) runners.add(new TestClassRunnerForObjects(getTestClass().getJavaClass(), objectsList, i)); diff --git a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java index 8b39810..7d2d250 100644 --- a/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java +++ b/src/test/java/buttondevteam/chat/components/formatter/ChatFormatIT.java @@ -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 list = new ArrayList(); + List 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 cfs = ChatProcessing.addFormatters(Color.White, p -> true, null); + ArrayList 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);