Merge pull request #72 from TBMCPlugins/dev

Chat fixes, town color fixes, some features
This commit is contained in:
Norbi Peti 2018-04-24 12:14:51 +02:00 committed by GitHub
commit 6202e30522
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 692 additions and 666 deletions

24
pom.xml
View file

@ -51,11 +51,6 @@
<include>org.javassist:javassist</include> <include>org.javassist:javassist</include>
</includes> </includes>
</artifactSet> </artifactSet>
<pluginExecution>
<action>
<execute />
</action>
</pluginExecution>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
@ -111,16 +106,16 @@
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository> </repository>
<repository> <repository>
<id>jitpack.io</id> <id>jitpack</id>
<url>https://jitpack.io/</url> <url>https://jitpack.io/</url>
</repository> </repository>
<repository> <repository>
<id>Essentials</id> <id>Essentials</id>
<url>http://repo.ess3.net/</url> <url>http://repo.ess3.net/content/repositories/essrel/</url>
</repository> </repository>
<repository> <repository>
<id>Votifier</id> <id>Votifier</id>
<url>http://repo.howaner.de/</url> <url>https://dl.bintray.com/nuvotifier/maven/</url>
</repository> </repository>
<repository> <repository>
<id>Minigames</id> <id>Minigames</id>
@ -172,8 +167,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.vexsoftware</groupId> <groupId>com.vexsoftware</groupId>
<artifactId>votifier</artifactId> <artifactId>nuvotifier-universal</artifactId>
<version>1.9</version> <version>2.3.4</version>
</dependency> </dependency>
<!-- <dependency> <groupId>au.com.mineauz</groupId> <artifactId>Minigames</artifactId> <!-- <dependency> <groupId>au.com.mineauz</groupId> <artifactId>Minigames</artifactId>
<version>1.8.0</version> </dependency> --> <version>1.8.0</version> </dependency> -->
@ -203,7 +198,14 @@
<dependency> <dependency>
<groupId>com.github.webbukkit</groupId> <groupId>com.github.webbukkit</groupId>
<artifactId>Dynmap</artifactId> <artifactId>Dynmap</artifactId>
<version>master-SNAPSHOT</version> <version>v2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<artifactId>ButtonChat</artifactId> <artifactId>ButtonChat</artifactId>

View file

@ -1,16 +1,17 @@
package buttondevteam.chat; package buttondevteam.chat;
import java.util.ArrayList; import buttondevteam.lib.chat.Channel;
import java.util.List; import buttondevteam.lib.chat.Color;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import buttondevteam.lib.chat.*;
import buttondevteam.lib.player.EnumPlayerData; import buttondevteam.lib.player.EnumPlayerData;
import buttondevteam.lib.player.PlayerClass; import buttondevteam.lib.player.PlayerClass;
import buttondevteam.lib.player.PlayerData; import buttondevteam.lib.player.PlayerData;
import buttondevteam.lib.player.TBMCPlayerBase; import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
@PlayerClass(pluginname = "Button1Chat") @PlayerClass(pluginname = "Button1Chat")
public class ChatPlayer extends TBMCPlayerBase { public class ChatPlayer extends TBMCPlayerBase {
@ -104,7 +105,7 @@ public class ChatPlayer extends TBMCPlayerBase {
// PluginMain.Instance.getServer().getScoreboardManager().getMainScoreboard().getTeams().add() // PluginMain.Instance.getServer().getScoreboardManager().getMainScoreboard().getTeams().add()
Player p = Bukkit.getPlayer(uuid); Player p = Bukkit.getPlayer(uuid);
if (p != null) if (p != null)
p.setPlayerListName(String.format("%s%s", p.getName(), GetFormattedFlair())); p.setPlayerListName(String.format("%s%s", p.getDisplayName(), GetFormattedFlair()));
} }
public short GetFlairColor() { public short GetFlairColor() {

View file

@ -1,385 +1,320 @@
package buttondevteam.chat; package buttondevteam.chat;
import java.util.ArrayList; import buttondevteam.chat.commands.UnlolCommand;
import java.util.Arrays; import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import java.util.Collection; import buttondevteam.chat.formatting.ChatFormatter;
import java.util.List; import buttondevteam.chat.formatting.TellrawEvent;
import java.util.concurrent.atomic.AtomicInteger; import buttondevteam.chat.formatting.TellrawPart;
import java.util.function.BiFunction; import buttondevteam.chat.formatting.TellrawSerializer;
import java.util.regex.Pattern; import buttondevteam.chat.listener.PlayerListener;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.*;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.Essentials;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Objective;
import com.earth2me.essentials.Essentials; import java.util.ArrayList;
import com.google.common.collect.Lists; import java.util.Collection;
import com.google.gson.Gson; import java.util.List;
import com.google.gson.GsonBuilder; import java.util.concurrent.atomic.AtomicInteger;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException; import java.util.regex.Pattern;
import buttondevteam.chat.commands.UnlolCommand;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import buttondevteam.chat.formatting.*;
import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatEventBase;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.TellrawSerializableEnum;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import lombok.val;
import buttondevteam.chat.listener.PlayerListener;
import buttondevteam.lib.chat.*;
public class ChatProcessing { public class ChatProcessing {
private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null"); private static final Pattern NULL_MENTION_PATTERN = Pattern.compile("null");
private static final Pattern CYAN_PATTERN = Pattern.compile("cyan"); private static final Pattern CYAN_PATTERN = Pattern.compile("cyan");
private static final Pattern ESCAPE_PATTERN = Pattern.compile("\\\\"); 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 CONSOLE_PING_PATTERN = Pattern.compile("(?i)" + Pattern.quote("@console"));
private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)"); private static final Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+)");
private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),]+)"); private static final Pattern URL_PATTERN = Pattern.compile("(http[\\w:/?=$\\-_.+!*'(),]+)");
private static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+"); private static final Pattern ENTIRE_MESSAGE_PATTERN = Pattern.compile(".+");
private static final Pattern UNDERLINED_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 = Pattern.compile("\\*");
private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*"); private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*");
private static final Pattern CODE_PATTERN = Pattern.compile("`"); private static final Pattern CODE_PATTERN = Pattern.compile("`");
private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]])\\]\\(([^\\(\\)])\\)"); private static final Pattern MASKED_LINK_PATTERN = Pattern.compile("\\[([^\\[\\]])\\]\\(([^()])\\)");
private static final Color[] RainbowPresserColors = new Color[] { Color.Red, Color.Gold, Color.Yellow, Color.Green, private static final Pattern SOMEONE_PATTERN = Pattern.compile("@someone"); //TODO
Color.Blue, Color.DarkPurple }; private static final Color[] RainbowPresserColors = new Color[]{Color.Red, Color.Gold, Color.Yellow, Color.Green,
private static boolean pingedconsole = false; Color.Blue, Color.DarkPurple};
private static boolean pingedconsole = false;
public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build(); public static final ChatFormatter ESCAPE_FORMATTER = ChatFormatter.builder().regex(ESCAPE_PATTERN).build();
private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList( private static ArrayList<ChatFormatter> commonFormatters = Lists.newArrayList(
ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).range(true) ChatFormatter.builder().regex(BOLD_PATTERN).bold(true).removeCharCount((short) 2).range(true)
.priority(Priority.High).build(), .priority(Priority.High).build(),
ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).range(true).build(), ChatFormatter.builder().regex(ITALIC_PATTERN).italic(true).removeCharCount((short) 1).range(true).build(),
ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).range(true) ChatFormatter.builder().regex(UNDERLINED_PATTERN).underlined(true).removeCharCount((short) 1).range(true)
.build(), .build(),
ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").build(), ESCAPE_FORMATTER, ChatFormatter.builder().regex(URL_PATTERN).underlined(true).openlink("$1").build(),
ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature ChatFormatter.builder().regex(NULL_MENTION_PATTERN).color(Color.DarkRed).build(), // Properly added a bug as a feature
ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> { ChatFormatter.builder().regex(CONSOLE_PING_PATTERN).color(Color.Aqua).onmatch((match, builder) -> {
if (!pingedconsole) { if (!pingedconsole) {
System.out.print("\007"); System.out.print("\007");
pingedconsole = true; // Will set it to false in ProcessChat pingedconsole = true; // Will set it to false in ProcessChat
} }
return match; return match;
}).priority(Priority.High).build(), }).priority(Priority.High).build(),
ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1") ChatFormatter.builder().regex(HASHTAG_PATTERN).color(Color.Blue).openlink("https://twitter.com/hashtag/$1")
.priority(Priority.High).build(), .priority(Priority.High).build(),
ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55 ChatFormatter.builder().regex(CYAN_PATTERN).color(Color.Aqua).build(), // #55
ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).range(true) ChatFormatter.builder().regex(CODE_PATTERN).color(Color.DarkGray).removeCharCount((short) 1).range(true)
.build(), .build(),
ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder) -> { ChatFormatter.builder().regex(MASKED_LINK_PATTERN).underlined(true).onmatch((match, builder) -> {
return match; // TODO! return match; // TODO!
}).build()); }).build());
private static Gson gson = new GsonBuilder() private static Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum()) .registerTypeHierarchyAdapter(TellrawSerializableEnum.class, new TellrawSerializer.TwEnum())
.registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection()) .registerTypeHierarchyAdapter(Collection.class, new TellrawSerializer.TwCollection())
.registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool()) .registerTypeAdapter(Boolean.class, new TellrawSerializer.TwBool())
.registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create(); .registerTypeAdapter(boolean.class, new TellrawSerializer.TwBool()).disableHtmlEscaping().create();
private ChatProcessing() { private ChatProcessing() {
} }
public static boolean ProcessChat(TBMCChatEvent e) { public static boolean ProcessChat(TBMCChatEvent e) {
Channel channel = e.getChannel(); Channel channel = e.getChannel();
CommandSender sender = e.getSender(); CommandSender sender = e.getSender();
String message = e.getMessage(); String message = e.getMessage();
long processstart = System.nanoTime(); long processstart = System.nanoTime();
if (PluginMain.essentials == null) if (PluginMain.essentials == null)
PluginMain.essentials = (Essentials) (Bukkit.getPluginManager().getPlugin("Essentials")); PluginMain.essentials = (Essentials) (Bukkit.getPluginManager().getPlugin("Essentials"));
Player player = (sender instanceof Player ? (Player) sender : null); Player player = (sender instanceof Player ? (Player) sender : null);
if (player != null && PluginMain.essentials.getUser(player).isMuted()) if (player != null && PluginMain.essentials.getUser(player).isMuted())
return true; return true;
doFunStuff(sender, e, message); doFunStuff(sender, e, message);
ChatPlayer mp = null; ChatPlayer mp = null;
if (player != null) if (player != null)
mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class); mp = TBMCPlayerBase.getPlayer(player.getUniqueId(), ChatPlayer.class);
Color colormode = channel.color; Color colormode = channel.color;
if (mp != null && mp.OtherColorMode != null) if (mp != null && mp.OtherColorMode != null)
colormode = mp.OtherColorMode; colormode = mp.OtherColorMode;
if (message.startsWith(">")) if (message.startsWith(">"))
colormode = Color.Green; colormode = Color.Green;
// If greentext, ignore channel or player colors // If greentext, ignore channel or player colors
ArrayList<ChatFormatter> formatters = addFormatters(colormode); ArrayList<ChatFormatter> formatters = addFormatters(colormode);
if (colormode == channel.color && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color if (colormode == channel.color && mp != null && mp.RainbowPresserColorMode) { // Only overwrite channel color
final AtomicInteger rpc = new AtomicInteger(0); final AtomicInteger rpc = new AtomicInteger(0);
formatters.add(ChatFormatter.builder().color(colormode).onmatch((match, cf) -> { formatters.add(ChatFormatter.builder().color(colormode).onmatch((match, cf) -> {
cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]); cf.setColor(RainbowPresserColors[rpc.getAndUpdate(i -> ++i < RainbowPresserColors.length ? i : 0)]);
return match; return match;
}).build()); }).build());
} }
pingedconsole = false; // Will set it to true onmatch (static constructor) pingedconsole = false; // Will set it to true onmatch (static constructor)
final String channelidentifier = getChannelID(channel, sender); final String channelidentifier = getChannelID(channel, sender);
TellrawPart json = createTellraw(sender, message, player, mp, channelidentifier); TellrawPart json = createTellraw(sender, message, player, mp, channelidentifier);
long combinetime = System.nanoTime(); long combinetime = System.nanoTime();
ChatFormatter.Combine(formatters, message, json); ChatFormatter.Combine(formatters, message, json);
combinetime = System.nanoTime() - combinetime; combinetime = System.nanoTime() - combinetime;
String jsonstr = toJson(json); String jsonstr = toJson(json);
if (jsonstr.length() >= 32767) { if (jsonstr.length() >= 32767) {
sender.sendMessage( sender.sendMessage(
"§cError: Message too long. Try shortening it, or remove hashtags and other formatting."); "§cError: Message too long. Try shortening it, or remove hashtags and other formatting.");
return true; return true;
} }
DebugCommand.SendDebugMessage(jsonstr); DebugCommand.SendDebugMessage(jsonstr);
try { try {
if (channel.filteranderrormsg != null) { if (channel.filteranderrormsg != null) {
Objective obj = PluginMain.SB.getObjective(channel.ID); Objective obj = PluginMain.SB.getObjective(channel.ID);
int score = -1; int score = -1;
for (Player p : Bukkit.getOnlinePlayers()) { for (Player p : Bukkit.getOnlinePlayers()) {
final int mcScore; final int mcScore;
if (player != null if (player != null
&& PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player))) && PluginMain.essentials.getUser(p).isIgnoredPlayer(PluginMain.essentials.getUser(player)))
mcScore = -1; // Don't send the message to them mcScore = -1; // Don't send the message to them
else else
mcScore = VanillaUtils.getMCScoreIfChatOn(p, e); mcScore = VanillaUtils.getMCScoreIfChatOn(p, e);
obj.getScore(p.getName()) obj.getScore(p.getName())
.setScore(p.getUniqueId().equals(player == null ? null : player.getUniqueId()) // p.UniqueID==player?.UniqueID .setScore(p.getUniqueId().equals(player == null ? null : player.getUniqueId()) // p.UniqueID==player?.UniqueID
? score = mcScore : mcScore); ? score = mcScore : mcScore);
} }
if (score == -1) // Even if the player object isn't null, it may not be in OnlinePlayers if (score == -1) // Even if the player object isn't null, it may not be in OnlinePlayers
score = e.getMCScore(sender); score = e.getMCScore(sender);
if (score < 0) // Never send messages to score below 0 if (score < 0) // Never send messages to score below 0
sender.sendMessage("§cYou don't have permission to send this message or something went wrong"); sender.sendMessage("§cYou don't have permission to send this message or something went wrong");
else { else {
PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console,
String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID, String.format("tellraw @a[score_%s=%d,score_%s_min=%d] %s", channel.ID, score, channel.ID,
score, jsonstr)); score, jsonstr));
if (e.getChannel().ID.equals(PluginMain.TownChat.ID) if (e.getChannel().ID.equals(PluginMain.TownChat.ID)
|| e.getChannel().ID.equals(PluginMain.NationChat.ID)) { || e.getChannel().ID.equals(PluginMain.NationChat.ID)) {
((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]")); ((List<TellrawPart>) json.getExtra()).add(0, new TellrawPart("[SPY]"));
jsonstr = toJson(json); jsonstr = toJson(json);
Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format( Bukkit.getServer().dispatchCommand(PluginMain.Console, String.format(
"tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr)); "tellraw @a[score_%s=1000,score_%s_min=1000] %s", channel.ID, channel.ID, jsonstr));
} }
} }
} else } else
PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console, PluginMain.Instance.getServer().dispatchCommand(PluginMain.Console,
String.format("tellraw @a %s", jsonstr)); String.format("tellraw @a %s", jsonstr));
} catch (Exception ex) { } catch (Exception ex) {
TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex); TBMCCoreAPI.SendException("An error occured while sending a chat message!", ex);
sender.sendMessage("§cAn error occured while sending the message."); sender.sendMessage("§cAn error occured while sending the message.");
return true; return true;
} }
PluginMain.Instance.getServer().getConsoleSender() PluginMain.Instance.getServer().getConsoleSender()
.sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message)); .sendMessage(String.format("%s <%s§r> %s", channelidentifier, getSenderName(sender, player), message));
DebugCommand.SendDebugMessage( DebugCommand.SendDebugMessage(
"-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms"); "-- Full ChatProcessing time: " + (System.nanoTime() - processstart) / 1000000f + " ms");
DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms"); DebugCommand.SendDebugMessage("-- ChatFormatter.Combine time: " + combinetime / 1000000f + " ms");
return false; return false;
} }
static String toJson(TellrawPart json) { static String toJson(TellrawPart json) {
String jsonstr = gson.toJson(json); return gson.toJson(json);
return jsonstr; }
}
static TellrawPart createTellraw(CommandSender sender, String message, Player player, ChatPlayer mp, static TellrawPart createTellraw(CommandSender sender, String message, Player player, ChatPlayer mp,
final String channelidentifier) { final String channelidentifier) {
TellrawPart json = new TellrawPart(""); TellrawPart json = new TellrawPart("");
if (mp != null && mp.ChatOnly) { if (mp != null && mp.ChatOnly) {
json.addExtra(new TellrawPart("[C]") json.addExtra(new TellrawPart("[C]")
.setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only"))); .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Chat only")));
} }
json.addExtra( json.addExtra(
new TellrawPart(channelidentifier) new TellrawPart(channelidentifier)
.setHoverEvent( .setHoverEvent(
TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT,
new TellrawPart((sender instanceof IDiscordSender ? "From Discord\n" : "") new TellrawPart((sender instanceof IDiscordSender ? "From Discord\n" : "")
+ "Copy message").setColor(Color.Blue))) + "Copy message").setColor(Color.Blue)))
.setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message))); .setClickEvent(TellrawEvent.create(TellrawEvent.ClickAction.SUGGEST_COMMAND, message)));
json.addExtra(new TellrawPart(" <")); if (PluginMain.permission.has(player, "tbmc.badge.diamond"))
json.addExtra( json.addExtra(new TellrawPart("[P]").setColor(Color.Aqua).setBold(true)
new TellrawPart( .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Diamond Patreon supporter")));
getSenderName( else if (PluginMain.permission.has(player, "tbmc.badge.gold"))
sender, player)) json.addExtra(new TellrawPart("[P]").setColor(Color.Gold).setBold(true)
.setHoverEvent( .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, "Gold Patreon supporter")));
TellrawEvent json.addExtra(new TellrawPart(" <"));
.create(TellrawEvent.HoverAction.SHOW_TEXT, TellrawPart hovertp = new TellrawPart("");
new TellrawPart("") if (mp != null)
.addExtra(new TellrawPart(String.format( hovertp.addExtra(new TellrawPart(mp.getInfo(ChromaGamerBase.InfoTarget.MCHover)));
"Flair: %s", json.addExtra(new TellrawPart(getSenderName(sender, player))
(mp != null ? mp.GetFormattedFlair() .setHoverEvent(TellrawEvent.create(TellrawEvent.HoverAction.SHOW_TEXT, hovertp)));
: "-")))) json.addExtra(new TellrawPart("> "));
.addExtra(new TellrawPart(String.format( return json;
"\nPlayername: %s\n", }
(player != null ? player.getName()
: sender.getName())))
.setColor(Color.Aqua))
.addExtra(new TellrawPart(String.format(
"World: %s\n",
(player != null
? player.getWorld().getName()
: "-"))))
.addExtra(new TellrawPart(String.format(
"Respect: %s%s%s",
(mp != null ? (mp.FCount().get()
/ (double) mp.FDeaths().get())
: "Infinite"),
(mp != null
&& mp.UserName().get() != null
&& !mp.UserName().get()
.isEmpty()
? "\nUserName: "
+ mp.UserName()
.get()
: ""),
(mp != null && mp.PlayerName().get()
.equals("\nAlpha_Bacca44")
? "\nDeaths: "
+ PlayerListener.AlphaDeaths
: ""))))
.addExtra(new TellrawPart(
"\nFor more, do /u info "
+ sender.getName())))));
json.addExtra(new TellrawPart("> "));
return json;
}
private static String getSenderName(CommandSender sender, Player player) { private static String getSenderName(CommandSender sender, Player player) {
if (player == null) if (player == null)
return sender.getName(); return sender.getName();
val res = PluginMain.TU.getResidentMap().get(player.getName().toLowerCase()); return player.getDisplayName();
if (res == null || !res.hasTown()) }
return player.getDisplayName();
try {
val clrs = PluginMain.TownColors.get(res.getTown().getName().toLowerCase());
if (clrs == null)
return player.getDisplayName();
StringBuilder ret = new StringBuilder();
String name = ChatColor.stripColor(player.getDisplayName());
AtomicInteger prevlen = new AtomicInteger();
BiFunction<Integer, Integer, String> coloredNamePart = (len, i) -> "§"
+ Integer.toHexString(clrs[i].ordinal()) // 'Odds' are the last character is chopped off so we make sure to include all chars at the end
+ (i + 1 == clrs.length ? name.substring(prevlen.get())
: name.substring(prevlen.get(), prevlen.addAndGet(len)));
int len = name.length() / clrs.length;
val nclar = ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations().get();
int[] ncl = nclar == null ? null : nclar.stream().mapToInt(Integer::intValue).toArray();
if (ncl != null && (Arrays.stream(ncl).sum() != name.length() || ncl.length != clrs.length))
ncl = null; // Reset if name length changed
if (name.charAt(0) == '~') { // Ignore ~ in nicknames
prevlen.incrementAndGet();
ret.append("~");
}
for (int i = 0; i < clrs.length; i++)
ret.append(coloredNamePart.apply(ncl == null ? len : ncl[i], i));
return ret.toString();
} catch (NotRegisteredException e) {
return player.getDisplayName();
}
}
static String getChannelID(Channel channel, CommandSender sender) { static String getChannelID(Channel channel, CommandSender sender) {
final String channelidentifier = ("[" + (sender instanceof IDiscordSender ? "d|" : "") + channel.DisplayName) return ("[" + (sender instanceof IDiscordSender ? "§bD§r|" : "") + channel.DisplayName)
+ "]"; + "]";
return channelidentifier; }
}
static ArrayList<ChatFormatter> addFormatters(Color colormode) { static ArrayList<ChatFormatter> addFormatters(Color colormode) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ArrayList<ChatFormatter> formatters = (ArrayList<ChatFormatter>) commonFormatters.clone(); ArrayList<ChatFormatter> formatters = (ArrayList<ChatFormatter>) commonFormatters.clone();
formatters.add( formatters.add(
ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build()); ChatFormatter.builder().regex(ENTIRE_MESSAGE_PATTERN).color(colormode).priority(Priority.Low).build());
if (Bukkit.getOnlinePlayers().size() > 0) { if (Bukkit.getOnlinePlayers().size() > 0) {
StringBuilder namesb = new StringBuilder("(?i)("); StringBuilder namesb = new StringBuilder("(?i)(");
for (Player p : Bukkit.getOnlinePlayers()) for (Player p : Bukkit.getOnlinePlayers())
namesb.append(p.getName()).append("|"); namesb.append(p.getName()).append("|");
namesb.deleteCharAt(namesb.length() - 1); namesb.deleteCharAt(namesb.length() - 1);
namesb.append(")"); namesb.append(")");
StringBuilder nicksb = new StringBuilder("(?i)("); StringBuilder nicksb = new StringBuilder("(?i)(");
boolean addNickFormatter = false; boolean addNickFormatter = false;
final int size = Bukkit.getOnlinePlayers().size(); final int size = Bukkit.getOnlinePlayers().size();
int index = 0; int index = 0;
for (Player p : Bukkit.getOnlinePlayers()) { for (Player p : Bukkit.getOnlinePlayers()) {
final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId()); final String nick = PlayerListener.nicknames.inverse().get(p.getUniqueId());
if (nick != null) { if (nick != null) {
nicksb.append(nick); nicksb.append(nick);
if (index < size - 1) { if (index < size - 1) {
nicksb.append("|"); nicksb.append("|");
addNickFormatter = true; addNickFormatter = true;
} }
} }
index++; index++;
} }
nicksb.append(")"); nicksb.append(")");
formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua) formatters.add(ChatFormatter.builder().regex(Pattern.compile(namesb.toString())).color(Color.Aqua)
.onmatch((match, builder) -> { .onmatch((match, builder) -> {
Player p = Bukkit.getPlayer(match); Player p = Bukkit.getPlayer(match);
if (p == null) { if (p == null) {
PluginMain.Instance.getLogger() PluginMain.Instance.getLogger()
.warning("Error: Can't find player " + match + " but was reported as online."); .warning("Error: Can't find player " + match + " but was reported as online.");
return "§c" + match + "§r"; return "§c" + match + "§r";
} }
ChatPlayer mpp = TBMCPlayer.getPlayer(p.getUniqueId(), ChatPlayer.class); ChatPlayer mpp = TBMCPlayer.getPlayer(p.getUniqueId(), ChatPlayer.class);
if (PlayerListener.NotificationSound == null) if (PlayerListener.NotificationSound == null)
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); // TODO: Airhorn
else else
p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f, p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
(float) PlayerListener.NotificationPitch); (float) PlayerListener.NotificationPitch);
String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor())); String color = String.format("§%x", (mpp.GetFlairColor() == 0x00 ? 0xb : mpp.GetFlairColor()));
return color + p.getName() + "§r"; return color + p.getName() + "§r";
}).priority(Priority.High).build()); }).priority(Priority.High).build());
if (addNickFormatter) if (addNickFormatter)
formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua) formatters.add(ChatFormatter.builder().regex((Pattern.compile(nicksb.toString()))).color(Color.Aqua)
.onmatch((match, builder) -> { .onmatch((match, builder) -> {
if (PlayerListener.nicknames.containsKey(match)) { if (PlayerListener.nicknames.containsKey(match)) {
Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match)); Player p = Bukkit.getPlayer(PlayerListener.nicknames.get(match));
if (p == null) { if (p == null) {
PluginMain.Instance.getLogger().warning("Error: Can't find player nicknamed " PluginMain.Instance.getLogger().warning("Error: Can't find player nicknamed "
+ match + " but was reported as online."); + match + " but was reported as online.");
return "§c" + match + "§r"; return "§c" + match + "§r";
} }
if (PlayerListener.NotificationSound == null) if (PlayerListener.NotificationSound == null)
p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f); p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1.0f, 0.5f);
else else
p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f, p.playSound(p.getLocation(), PlayerListener.NotificationSound, 1.0f,
(float) PlayerListener.NotificationPitch); (float) PlayerListener.NotificationPitch);
return PluginMain.essentials.getUser(p).getNickname(); return PluginMain.essentials.getUser(p).getNickname();
} }
Bukkit.getServer().getLogger().warning("Player nicknamed " + match Bukkit.getServer().getLogger().warning("Player nicknamed " + match
+ " not found in nickname map but was reported as online."); + " not found in nickname map but was reported as online.");
return "§c" + match + "§r"; return "§c" + match + "§r";
}).priority(Priority.High).build()); }).priority(Priority.High).build());
} }
return formatters; return formatters;
} }
static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) { static void doFunStuff(CommandSender sender, TBMCChatEventBase event, String message) {
if (PlayerListener.ActiveF && !PlayerListener.Fs.contains(sender) && message.equalsIgnoreCase("F")) if (PlayerListener.ActiveF && !PlayerListener.Fs.contains(sender) && message.equalsIgnoreCase("F"))
PlayerListener.Fs.add(sender); PlayerListener.Fs.add(sender);
String msg = message.toLowerCase(); String msg = message.toLowerCase();
val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime()); val lld = new UnlolCommand.LastlolData(sender, event, System.nanoTime());
boolean add = false; boolean add;
if (add = msg.contains("lol")) if (add = msg.contains("lol"))
lld.setLolornot(true); lld.setLolornot(true);
else { else {
for (int i = 0; i < PlayerListener.LaughStrings.length; i++) { for (int i = 0; i < PlayerListener.LaughStrings.length; i++) {
if (add = msg.contains(PlayerListener.LaughStrings[i])) { if (add = msg.contains(PlayerListener.LaughStrings[i])) {
lld.setLolornot(false); lld.setLolornot(false);
break; break;
} }
} }
} }
if (add) if (add)
UnlolCommand.Lastlol.put(event.getChannel(), lld); UnlolCommand.Lastlol.put(event.getChannel(), lld);
} }
} }

View file

@ -1,9 +1,28 @@
package buttondevteam.chat; package buttondevteam.chat;
import buttondevteam.chat.commands.YeehawCommand;
import buttondevteam.chat.commands.ucmds.TownColorCommand;
import buttondevteam.chat.listener.PlayerListener;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.Channel.RecipientTestResult;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.Essentials;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import lombok.val;
import net.milkbowl.vault.chat.Chat; import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
@ -17,45 +36,15 @@ import org.dynmap.towny.DynmapTownyPlugin;
import org.htmlcleaner.HtmlCleaner; import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode; import org.htmlcleaner.TagNode;
import buttondevteam.chat.commands.YeehawCommand; import java.io.File;
import buttondevteam.chat.commands.ucmds.TownColorCommand; import java.io.IOException;
import buttondevteam.chat.listener.PlayerListener; import java.io.InputStream;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.Channel.RecipientTestResult;
import buttondevteam.lib.player.TBMCPlayerBase;
import lombok.val;
import com.earth2me.essentials.Essentials;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import java.io.*;
import java.lang.String;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -120,9 +109,8 @@ public class PluginMain extends JavaPlugin { // Translated to Java: 2015.07.15.
setTownColor(dtp, entry.getKey(), entry.getValue()); setTownColor(dtp, entry.getKey(), entry.getValue());
}); });
setupChat(); if (!setupEconomy() || !setupPermissions())
setupEconomy(); TBMCCoreAPI.SendException("We're in trouble", new Exception("Failed to set up economy or permissions!"));
setupPermissions();
new Thread(this::FlairGetterThreadMethod).start(); new Thread(this::FlairGetterThreadMethod).start();
new Thread(new AnnouncerThread()).start(); new Thread(new AnnouncerThread()).start();
@ -296,17 +284,18 @@ public class PluginMain extends JavaPlugin { // Translated to Java: 2015.07.15.
yc.load(file); yc.load(file);
PlayerListener.NotificationSound = yc.getString("notificationsound"); PlayerListener.NotificationSound = yc.getString("notificationsound");
PlayerListener.NotificationPitch = yc.getDouble("notificationpitch"); PlayerListener.NotificationPitch = yc.getDouble("notificationpitch");
AnnounceTime = yc.getInt("announcetime"); AnnounceTime = yc.getInt("announcetime", 15 * 60 * 1000);
AnnounceMessages.addAll(yc.getStringList("announcements")); AnnounceMessages.addAll(yc.getStringList("announcements"));
PlayerListener.AlphaDeaths = yc.getInt("alphadeaths"); PlayerListener.AlphaDeaths = yc.getInt("alphadeaths");
val cs = yc.getConfigurationSection("towncolors"); val cs = yc.getConfigurationSection("towncolors");
if (cs != null) if (cs != null)
TownColors.putAll(cs.getValues(true).entrySet().stream() TownColors.putAll(cs.getValues(true).entrySet().stream()
.collect(Collectors.toMap(k -> k.getKey(), v -> ((List<String>) v.getValue()).stream() .collect(Collectors.toMap(Map.Entry::getKey, v -> ((List<String>) v.getValue()).stream()
.map(c -> Color.valueOf(c)).toArray(Color[]::new)))); .map(Color::valueOf).toArray(Color[]::new))));
TownColorCommand.ColorCount = (byte) yc.getInt("towncolorcount", 1); TownColorCommand.ColorCount = (byte) yc.getInt("towncolorcount", 1);
} PluginMain.Instance.getLogger().info("Loaded files!");
PluginMain.Instance.getLogger().info("Loaded files!"); } else
PluginMain.Instance.getLogger().info("No files to load, first run probably.");
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("Error while loading chat files!", e); TBMCCoreAPI.SendException("Error while loading chat files!", e);
} }
@ -323,7 +312,7 @@ public class PluginMain extends JavaPlugin { // Translated to Java: 2015.07.15.
yc.set("announcements", AnnounceMessages); yc.set("announcements", AnnounceMessages);
yc.set("alphadeaths", PlayerListener.AlphaDeaths); yc.set("alphadeaths", PlayerListener.AlphaDeaths);
yc.createSection("towncolors", TownColors.entrySet().stream().collect(Collectors.toMap(k -> k.getKey(), yc.createSection("towncolors", TownColors.entrySet().stream().collect(Collectors.toMap(k -> k.getKey(),
v -> Arrays.stream(v.getValue()).map(c -> c.toString()).toArray(String[]::new)))); v -> Arrays.stream(v.getValue()).map(Enum::toString).toArray(String[]::new))));
yc.set("towncolorcount", TownColorCommand.ColorCount); yc.set("towncolorcount", TownColorCommand.ColorCount);
yc.save(file); yc.save(file);
PluginMain.Instance.getLogger().info("Saved files!"); PluginMain.Instance.getLogger().info("Saved files!");

View file

@ -0,0 +1,43 @@
package buttondevteam.chat.commands;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase;
import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Arrays;
import java.util.UUID;
@CommandClass
public class FTopCommand extends TBMCCommandBase {
@Override
public String[] GetHelpText(String arg0) {
return new String[]{ //
"§6---- F Top ----", //
"Shows the respect leaderboard" //
};
}
private final File playerdir = new File(TBMCPlayerBase.TBMC_PLAYERS_DIR);
private ChatPlayer[] cached;
private long lastcache = 0;
@Override
public boolean OnCommand(CommandSender arg0, String arg1, String[] arg2) {
if (cached == null || lastcache < System.nanoTime() - 60000000000L) { // 1m - (no guarantees of nanoTime's relation to 0, so we need the null check too)
cached = Arrays.stream(playerdir.listFiles())
.map(f -> TBMCPlayerBase.getPlayer(
UUID.fromString(f.getName().substring(0, f.getName().length() - 4)), ChatPlayer.class))
.sorted((cp1, cp2) -> Float.compare((float) cp2.FCount().get() / (float) cp2.FDeaths().get(),
(float) cp1.FCount().get() / (float) cp1.FDeaths().get()))
.toArray(ChatPlayer[]::new); // TODO: Properly implement getting all players
lastcache = System.nanoTime();
}
Arrays.stream(cached).limit(10);
return true;
}
}

View file

@ -1,45 +0,0 @@
package buttondevteam.chat.commands;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.listener.PlayerListener;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase;
import buttondevteam.lib.player.TBMCPlayer;
@CommandClass(modOnly = false)
public class WaitWhatCommand extends TBMCCommandBase {
@Override
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
Channel channel;
if (sender instanceof Player && ((Player) sender).isOnline())
channel = TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), ChatPlayer.class).CurrentChannel;
else if (sender instanceof ConsoleCommandSender)
channel = PlayerListener.ConsoleChannel;
else
channel = Channel.GlobalChat;
final String message;
if (args.length == 0)
message = "wait what";
else
message = "wait " + Arrays.stream(args).collect(Collectors.joining(" ")) + " what";
TBMCChatAPI.SendChatMessage(channel, sender, message);
return true;
}
@Override
public String[] GetHelpText(String alias) {
return new String[] { //
"§6--- Wait what ----", //
"Wait what" //
};
}
}

View file

@ -0,0 +1,19 @@
package buttondevteam.chat.commands.appendtext;
import buttondevteam.lib.chat.CommandClass;
@CommandClass(modOnly = false)
public class WaitWhatCommand extends AppendTextCommandBase {
@Override
public String[] GetHelpText(String alias) {
return new String[] { //
"§6--- Wait what ----", //
"Wait what" //
};
}
@Override
public String GetAppendedText() {
return "wait what";
}
}

View file

@ -1,21 +1,20 @@
package buttondevteam.chat.commands.ucmds; package buttondevteam.chat.commands.ucmds;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.PluginMain;
import buttondevteam.chat.listener.PlayerJoinLeaveListener;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.OptionallyPlayerCommandClass;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.PluginMain;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.OptionallyPlayerCommandClass;
@OptionallyPlayerCommandClass(playerOnly = true) @OptionallyPlayerCommandClass(playerOnly = true)
@CommandClass @CommandClass
public class NColorCommand extends UCommandBase { public class NColorCommand extends UCommandBase {
@ -46,6 +45,7 @@ public class NColorCommand extends UCommandBase {
} }
if (args.length == 0) if (args.length == 0)
return false; return false;
String arg = player.getDisplayName().startsWith("~") ? "~" + args[0] : args[0]; //Add ~ for nicknames
if (!args[0].replace("|", "").equalsIgnoreCase(ChatColor.stripColor(player.getDisplayName()))) { if (!args[0].replace("|", "").equalsIgnoreCase(ChatColor.stripColor(player.getDisplayName()))) {
player.sendMessage("§cThe name you gave doesn't match your name. Make sure to use " player.sendMessage("§cThe name you gave doesn't match your name. Make sure to use "
+ ChatColor.stripColor(player.getDisplayName()) + "§c with added vertical lines (|)."); + ChatColor.stripColor(player.getDisplayName()) + "§c with added vertical lines (|).");
@ -58,20 +58,21 @@ public class NColorCommand extends UCommandBase {
return true; return true;
} }
if (nameparts.length < towncolors.length) { if (nameparts.length < towncolors.length) {
player.sendMessage("§cYou need more vertical lines (|) in your name."); player.sendMessage("§cYou need more vertical lines (|) in your name. (Should have " + (towncolors.length - 1) + ")");
return true; return true;
} }
if (nameparts.length > towncolors.length * 2) { if (nameparts.length > towncolors.length * 2) {
player.sendMessage("§cYou have waay too many vertical lines (|) in your name."); player.sendMessage("§cYou have waay too many vertical lines (|) in your name. (Should have " + (towncolors.length - 1) + ")");
return true; return true;
} }
if (nameparts.length > towncolors.length) { if (nameparts.length > towncolors.length) {
player.sendMessage("§cYou have too many vertical lines (|) in your name."); player.sendMessage("§cYou have too many vertical lines (|) in your name. (Should have " + (towncolors.length - 1) + ")");
return true; return true;
} }
ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations() ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations()
.set(new ArrayList<>(Arrays.stream(nameparts).map(np -> np.length()).collect(Collectors.toList()))); // No byte[], no TIntArrayList .set(new ArrayList<>(Arrays.stream(nameparts).map(np -> np.length()).collect(Collectors.toList()))); // No byte[], no TIntArrayList
player.sendMessage("§bName colors set."); PlayerJoinLeaveListener.updatePlayerColors(player);
player.sendMessage("§bName colors set: " + player.getDisplayName());
return true; return true;
} }
} }

View file

@ -1,58 +1,74 @@
package buttondevteam.chat.commands.ucmds.admin; package buttondevteam.chat.commands.ucmds.admin;
import java.util.Arrays; import buttondevteam.chat.PluginMain;
import buttondevteam.chat.listener.PlayerJoinLeaveListener;
import buttondevteam.lib.chat.Color;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Town;
import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.dynmap.towny.DynmapTownyPlugin; import org.dynmap.towny.DynmapTownyPlugin;
import buttondevteam.chat.PluginMain; import java.util.Arrays;
import buttondevteam.lib.chat.Color; import java.util.stream.Collectors;
import lombok.val;
public class TownColorCommand extends AdminCommandBase { public class TownColorCommand extends AdminCommandBase {
@Override @Override
public String GetHelpText(String alias)[] { // TODO: Command path aliases public String GetHelpText(String alias)[] { // TODO: Command path aliases
return new String[] { // return new String[]{ //
"§6---- Town Color ----", // "§6---- Town Color ----", //
"This command allows setting a color for a town.", // "This command allows setting a color for a town.", //
"The town will be shown with this color on Dynmap and all players in the town will appear in chat with these colors.", // "The 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.", // "The colors will split the name evenly.", //
"Usage: /" + GetCommandPath() + " <town> <colorname1> [colorname2...]", // "Usage: /" + GetCommandPath() + " <town> <colorname1> [colorname2...]", //
"Example: /" + GetCommandPath() + " Alderon blue gray" // "Example: /" + GetCommandPath() + " Alderon blue gray" //
}; };
} }
@Override @Override
public boolean OnCommand(CommandSender sender, String alias, String[] args) { public boolean OnCommand(CommandSender sender, String alias, String[] args) {
return SetTownColor(sender, alias, args); return SetTownColor(sender, alias, args);
} }
public static boolean SetTownColor(CommandSender sender, String alias, String[] args) { public static boolean SetTownColor(CommandSender sender, String alias, String[] args) {
if (args.length < 2) if (args.length < 2)
return false; return false;
if (!PluginMain.TU.getTownsMap().containsKey(args[0].toLowerCase())) { if (!PluginMain.TU.getTownsMap().containsKey(args[0].toLowerCase())) {
sender.sendMessage("§cThe town '" + args[0] + "' cannot be found."); sender.sendMessage("§cThe town '" + args[0] + "' cannot be found.");
return true; return true;
} }
val clrs = new Color[args.length - 1]; val clrs = new Color[args.length - 1];
for (int i = 1; i < args.length; i++) { for (int i = 1; i < args.length; i++) {
val ii = i; val ii = i;
val c = Arrays.stream(Color.values()).filter(cc -> cc.getName().equalsIgnoreCase(args[ii])).findAny(); val c = Arrays.stream(Color.values()).skip(1).filter(cc -> cc.getName().equalsIgnoreCase(args[ii])).findAny();
if (!c.isPresent()) { if (!c.isPresent()) { //^^ Skip black
sender.sendMessage("§cThe color '" + args[i] + "' cannot be found."); sender.sendMessage("§cThe color '" + args[i] + "' cannot be found."); //ˇˇ Skip black
return true; sender.sendMessage("§cAvailable colors: " + Arrays.stream(Color.values()).skip(1).map(col -> String.format("§%x%s§r", col.ordinal(), col.getName())).collect(Collectors.joining(", ")));
} sender.sendMessage("§cMake sure to type them exactly as shown above.");
clrs[i - 1] = c.get(); return true;
} }
PluginMain.TownColors.put(args[0].toLowerCase(), clrs); clrs[i - 1] = c.get();
val dtp = (DynmapTownyPlugin) Bukkit.getPluginManager().getPlugin("Dynmap-Towny"); }
if (dtp == null) { PluginMain.TownColors.put(args[0].toLowerCase(), clrs);
sender.sendMessage("§cDynmap-Towny couldn'5 be found to set town color."); //PluginMain.TU.getTownsMap().get(args[0].toLowerCase()).getResidents().forEach(r->{
return true; Bukkit.getOnlinePlayers().forEach(p -> {
} try {
PluginMain.setTownColor(dtp, args[0].toLowerCase(), clrs); Town t = PluginMain.TU.getResidentMap().get(p.getName().toLowerCase()).getTown();
sender.sendMessage("§bColor(s) set."); if (t != null && t.getName().equalsIgnoreCase(args[0]))
return true; PlayerJoinLeaveListener.updatePlayerColors(p);
} } catch (NotRegisteredException e) {
}
});
val dtp = (DynmapTownyPlugin) Bukkit.getPluginManager().getPlugin("Dynmap-Towny");
if (dtp == null) {
sender.sendMessage("§cDynmap-Towny couldn't be found §6but otherwise §btown color set.");
PluginMain.Instance.getLogger().warning("Dynmap-Towny not found for setting town color!");
return true;
}
PluginMain.setTownColor(dtp, args[0].toLowerCase(), clrs);
sender.sendMessage("§bColor(s) set.");
return true;
}
} }

View file

@ -1,20 +1,19 @@
package buttondevteam.chat.formatting; package buttondevteam.chat.formatting;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import buttondevteam.chat.ChatProcessing; import buttondevteam.chat.ChatProcessing;
import buttondevteam.chat.commands.ucmds.admin.DebugCommand; import buttondevteam.chat.commands.ucmds.admin.DebugCommand;
import buttondevteam.lib.chat.*; import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.Priority;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.val;
import java.util.*;
import java.util.function.BiFunction;
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)} is used to turn it into a {@link TellrawPart}, combining * A {@link ChatFormatter} shows what formatting to use based on regular expressions. {@link ChatFormatter#Combine(List, String, TellrawPart)} is used to turn it into a {@link TellrawPart}, combining
@ -61,14 +60,20 @@ public final class ChatFormatter {
if (groups.size() > 0) if (groups.size() > 0)
DebugCommand.SendDebugMessage("First group: " + groups.get(0)); DebugCommand.SendDebugMessage("First group: " + groups.get(0));
FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups, FormattedSection section = new FormattedSection(formatter, matcher.start(), matcher.end() - 1, groups,
formatter.removeCharCount, formatter.removeCharCount, formatter.range); formatter.range);
sections.add(section); sections.add(section);
} }
} }
sections.sort((s1, s2) -> s1.Start == s2.Start sections.sort(
? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), (s1, s2) -> s1.Start == s2.Start
s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End) ? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
: Integer.compare(s1.Start, s2.Start)); s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End)
: Integer.compare(s1.Start, s2.Start));
/**
* 0: Start - 1: End
*/
val remchars = new ArrayList<int[]>();
header("Range section conversion"); header("Range section conversion");
ArrayList<FormattedSection> combined = new ArrayList<>(); ArrayList<FormattedSection> combined = new ArrayList<>();
@ -82,9 +87,9 @@ public final class ChatFormatter {
if (!section.IsRange) { if (!section.IsRange) {
escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second escaped = section.Formatters.contains(ChatProcessing.ESCAPE_FORMATTER) && !escaped; // Enable escaping on first \, disable on second
if (escaped) // Don't add the escape character if (escaped) // Don't add the escape character
section.RemCharFromStart = 1; remchars.add(new int[] { section.Start, section.Start + 1 });
combined.add(section); combined.add(section); // This will delete the \
DebugCommand.SendDebugMessage("Added " + (!escaped ? "not " : "") + "escaped section: " + section); DebugCommand.SendDebugMessage("Added " + (!escaped ? "not " : "") + "escaper section: " + section);
sendMessageWithPointer(str, section.Start, section.End); sendMessageWithPointer(str, section.Start, section.End);
continue; continue;
} }
@ -99,7 +104,7 @@ public final class ChatFormatter {
/* /*
* if (nextSection.containsKey(section.Formatters.get(0)) ? section.RemCharFromStart <= takenEnd - takenStart : section.RemCharFromStart > takenEnd - takenStart) { * if (nextSection.containsKey(section.Formatters.get(0)) ? section.RemCharFromStart <= takenEnd - takenStart : section.RemCharFromStart > takenEnd - takenStart) {
*/ */
if (section.RemCharFromStart < takenEnd - takenStart) { if (section.Formatters.get(0).removeCharCount < takenEnd - takenStart) {
DebugCommand.SendDebugMessage("Lose: " + section); DebugCommand.SendDebugMessage("Lose: " + section);
sendMessageWithPointer(str, section.Start, section.End); sendMessageWithPointer(str, section.Start, section.End);
DebugCommand.SendDebugMessage("And win: " + takenFormatter); DebugCommand.SendDebugMessage("And win: " + takenFormatter);
@ -111,11 +116,11 @@ public final class ChatFormatter {
DebugCommand.SendDebugMessage("And lose: " + takenFormatter); DebugCommand.SendDebugMessage("And lose: " + takenFormatter);
} }
takenStart = section.Start; takenStart = section.Start;
takenEnd = section.Start + section.RemCharFromStart; takenEnd = section.Start + section.Formatters.get(0).removeCharCount;
takenFormatter = section.Formatters.get(0); takenFormatter = section.Formatters.get(0);
if (nextSection.containsKey(section.Formatters.get(0))) { if (nextSection.containsKey(section.Formatters.get(0))) {
FormattedSection s = nextSection.remove(section.Formatters.get(0)); FormattedSection s = nextSection.remove(section.Formatters.get(0));
s.End = section.Start + section.RemCharFromStart - 1; s.End = section.Start; // section: the ending marker section - s: the to-be full section
// s.IsRange = false; // IsRange means it's a 1 long section indicating a start or an end // s.IsRange = false; // IsRange means it's a 1 long section indicating a start or an end
combined.add(s); combined.add(s);
DebugCommand.SendDebugMessage("Finished section: " + s); DebugCommand.SendDebugMessage("Finished section: " + s);
@ -129,11 +134,30 @@ public final class ChatFormatter {
.SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter); .SendDebugMessage("New area taken: (" + takenStart + "-" + takenEnd + ") " + takenFormatter);
sendMessageWithPointer(str, takenStart, takenEnd); sendMessageWithPointer(str, takenStart, takenEnd);
} else { } else {
DebugCommand.SendDebugMessage("Skipping section: " + section); DebugCommand.SendDebugMessage("Skipping section: " + section); // This will keep the text (character)
sendMessageWithPointer(str, section.Start, section.End); sendMessageWithPointer(str, section.Start, section.End);
escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*' escaped = false; // Reset escaping if applied, like if we're at the '*' in '\*'
} }
} }
for (val sec : nextSection.values()) {
sec.End = str.length() - 1;
combined.add(sec);
DebugCommand.SendDebugMessage("Finished unfinished section: " + sec);
sendMessageWithPointer(str, sec.Start, sec.End);
}
header("Adding remove chars (RC)"); // Important to add after the range section conversion
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 }))
.forEach(rc -> remchars.add(rc));
sections.stream()
.flatMap(fs -> fs.Formatters.stream().filter(cf -> cf.removeCharCount > 0)
.mapToInt(cf -> cf.removeCharCount).mapToObj(rcc -> new int[] { fs.End, fs.End - rcc }))
.forEach(rc -> remchars.add(rc));
DebugCommand.SendDebugMessage("Added remchars:");
DebugCommand
.SendDebugMessage(remchars.stream().map(rc -> Arrays.toString(rc)).collect(Collectors.joining("; ")));
header("Section combining"); header("Section combining");
sections = combined; sections = combined;
@ -152,23 +176,11 @@ public final class ChatFormatter {
if (firstSection.Start == sections.get(i).Start && firstSection.End == sections.get(i).End) { if (firstSection.Start == sections.get(i).Start && firstSection.End == sections.get(i).End) {
firstSection.Formatters.addAll(sections.get(i).Formatters); firstSection.Formatters.addAll(sections.get(i).Formatters);
firstSection.Matches.addAll(sections.get(i).Matches); firstSection.Matches.addAll(sections.get(i).Matches);
if (firstSection.RemCharFromStart < sections.get(i).RemCharFromStart)
firstSection.RemCharFromStart = sections.get(i).RemCharFromStart;
if (firstSection.RemCharFromEnd < sections.get(i).RemCharFromEnd)
firstSection.RemCharFromEnd = sections.get(i).RemCharFromEnd;
DebugCommand.SendDebugMessage("To section " + firstSection); DebugCommand.SendDebugMessage("To section " + firstSection);
sendMessageWithPointer(str, firstSection.Start, firstSection.End); sendMessageWithPointer(str, firstSection.Start, firstSection.End);
sections.remove(i); sections.remove(i);
found = true; found = true;
} else if (firstSection.End > sections.get(i).Start && firstSection.Start < sections.get(i).End) { } else if (firstSection.End > sections.get(i).Start && firstSection.Start < sections.get(i).End) {
int[][][] rc = new int[3][2][2]; // Remove characters - Section start/end positions
// [section number][start/end][remchar start/end]
rc[0][0] = new int[] { firstSection.Start, firstSection.Start + firstSection.RemCharFromStart };
rc[0][1] = new int[] { firstSection.End - firstSection.RemCharFromEnd, firstSection.End }; // Keep it in ascending order
// The third section doesn't have characters to remove yet
rc[2] = new int[][] {
{ sections.get(i).Start, sections.get(i).Start + sections.get(i).RemCharFromStart },
{ sections.get(i).End - sections.get(i).RemCharFromEnd, sections.get(i).End } }; // Keep it in ascending order
int origend = firstSection.End; int origend = firstSection.End;
firstSection.End = sections.get(i).Start - 1; firstSection.End = sections.get(i).Start - 1;
int origend2 = sections.get(i).End; int origend2 = sections.get(i).End;
@ -180,7 +192,7 @@ public final class ChatFormatter {
} }
// int rc1start, rc1end, rc2start, rc2end, rc3start, rc3end; // Remove characters - TODO: Store positions // int rc1start, rc1end, rc2start, rc2end, rc3start, rc3end; // Remove characters - TODO: Store positions
FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend, FormattedSection section = new FormattedSection(firstSection.Formatters, sections.get(i).Start, origend,
firstSection.Matches, (short) 0, (short) 0, false); firstSection.Matches, false);
section.Formatters.addAll(sections.get(i).Formatters); section.Formatters.addAll(sections.get(i).Formatters);
section.Matches.addAll(sections.get(i).Matches); // TODO: Clean section.Matches.addAll(sections.get(i).Matches); // TODO: Clean
sections.add(i, section); sections.add(i, section);
@ -194,34 +206,10 @@ public final class ChatFormatter {
} }
thirdFormattedSection.Start = origend + 1; thirdFormattedSection.Start = origend + 1;
thirdFormattedSection.End = origend2; thirdFormattedSection.End = origend2;
DebugCommand.SendDebugMessage("RC start");
for (short ii = 0; ii < 3; ii += 2) // Only check first and third section
for (short iii = 0; iii < 2; iii++) {
final int startorend = iii == 0 ? section.Start : section.End;
if (rc[ii][iii][0] <= startorend && rc[ii][iii][1] >= startorend) {
final String startorendText = iii == 0 ? "Start" : "End";
DebugCommand.SendDebugMessage("rc[" + ii + "][" + iii + "][0] <= section." + startorendText
+ " && rc[" + ii + "][" + iii + "][1] >= section." + startorendText);
DebugCommand.SendDebugMessage(rc[ii][iii][0] + " <= " + startorend + " && " + rc[ii][iii][1]
+ " >= " + startorend);
rc[1][iii] = new int[] { startorend, rc[ii][iii][1] };
rc[ii][iii][1] = startorend - 1;
DebugCommand.SendDebugMessage("rc[1][" + iii + "]: " + rc[1][iii][0] + " " + rc[1][iii][1]);
DebugCommand.SendDebugMessage("rc[" + ii + "][" + iii + "][1]: " + rc[ii][iii][1]);
}
}
DebugCommand.SendDebugMessage("RC done");
Function<int[], Integer> getRemCharStart = arr -> arr[1] - arr[0] < 0 ? 0 : arr[1] - arr[0];
firstSection.RemCharFromStart = (short) (int) getRemCharStart.apply(rc[0][0]);
firstSection.RemCharFromEnd = (short) (int) getRemCharStart.apply(rc[0][1]);
section.RemCharFromStart = (short) (int) getRemCharStart.apply(rc[1][0]);
section.RemCharFromEnd = (short) (int) getRemCharStart.apply(rc[1][1]);
thirdFormattedSection.RemCharFromStart = (short) (int) getRemCharStart.apply(rc[2][0]);
thirdFormattedSection.RemCharFromEnd = (short) (int) getRemCharStart.apply(rc[2][1]);
ArrayList<FormattedSection> sts = sections; ArrayList<FormattedSection> sts = sections;
Predicate<FormattedSection> removeIfNeeded = s -> { Predicate<FormattedSection> removeIfNeeded = s -> {
if (s.Start < 0 || s.End < 0 || s.Start > s.End || s.RemCharFromStart < 0 || s.RemCharFromEnd < 0) { if (s.Start < 0 || s.End < 0 || s.Start > s.End) {
DebugCommand.SendDebugMessage("Removing section: " + s); DebugCommand.SendDebugMessage("Removing section: " + s);
sendMessageWithPointer(str, s.Start, s.End); sendMessageWithPointer(str, s.Start, s.End);
sts.remove(s); sts.remove(s);
@ -246,8 +234,7 @@ public final class ChatFormatter {
found = true; found = true;
} }
for (int j = i - 1; j <= i + 1; j++) { for (int j = i - 1; j <= i + 1; j++) {
if (j < sections.size() && sections.get(j).End - sections.get(j).RemCharFromEnd < sections.get(j).Start if (j < sections.size() && sections.get(j).End < sections.get(j).Start) {
+ sections.get(j).RemCharFromStart) {
DebugCommand.SendDebugMessage("Removing section: " + sections.get(j)); DebugCommand.SendDebugMessage("Removing section: " + sections.get(j));
sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End); sendMessageWithPointer(str, sections.get(j).Start, sections.get(j).End);
sections.remove(j); sections.remove(j);
@ -260,10 +247,13 @@ public final class ChatFormatter {
if (found) { if (found) {
i = 1; i = 1;
found = false; found = false;
sections.sort((s1, s2) -> s1.Start == s2.Start sections.sort(
? s1.End == s2.End ? Integer.compare(s2.Formatters.get(0).priority.GetValue(), (s1, s2) -> s1.Start == s2.Start
s1.Formatters.get(0).priority.GetValue()) : Integer.compare(s2.End, s1.End) ? s1.End == s2.End
: Integer.compare(s1.Start, s2.Start)); ? Integer.compare(s2.Formatters.get(0).priority.GetValue(),
s1.Formatters.get(0).priority.GetValue())
: Integer.compare(s2.End, s1.End)
: Integer.compare(s1.Start, s2.Start));
} else } else
cont = false; cont = false;
} }
@ -274,10 +264,22 @@ public final class ChatFormatter {
FormattedSection section = sections.get(i); FormattedSection section = sections.get(i);
DebugCommand.SendDebugMessage("Applying section: " + section); DebugCommand.SendDebugMessage("Applying section: " + section);
String originaltext; String originaltext;
int start = section.Start + section.RemCharFromStart, end = section.End + 1 - section.RemCharFromEnd; int start = section.Start, end = section.End;
DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end); DebugCommand.SendDebugMessage("Start: " + start + " - End: " + end);
sendMessageWithPointer(str, start, end); sendMessageWithPointer(str, start, end);
originaltext = str.substring(start, end); val rcs = remchars.stream().filter(rc -> rc[0] <= start && start <= rc[1]).findAny();
val rce = remchars.stream().filter(rc -> rc[0] <= end && end <= rc[1]).findAny();
int s = start, e = end;
if (rcs.isPresent())
s = rcs.get()[1];
if (rce.isPresent())
e = rce.get()[0];
DebugCommand.SendDebugMessage("After RC - Start: " + s + " - End: " + e);
if (e - s < 0) { //e-s==0 means the end char is the same as start char, so one char message
DebugCommand.SendDebugMessage("Skipping section because of remchars (length would be " + (e - s + 1) + ")");
continue;
}
originaltext = str.substring(s, e + 1);
DebugCommand.SendDebugMessage("Section text: " + originaltext); DebugCommand.SendDebugMessage("Section text: " + originaltext);
Color color = null; Color color = null;
boolean bold = false, italic = false, underlined = false, strikethrough = false, obfuscated = false; boolean bold = false, italic = false, underlined = false, strikethrough = false, obfuscated = false;
@ -322,15 +324,10 @@ public final class ChatFormatter {
header("ChatFormatter.Combine done"); header("ChatFormatter.Combine done");
} }
/**
*
* @param str
* @param pointer
* This must be ordered ascending
*/
private static void sendMessageWithPointer(String str, int... pointer) { private static void sendMessageWithPointer(String str, int... pointer) {
DebugCommand.SendDebugMessage(str); DebugCommand.SendDebugMessage(str);
StringBuilder sb = new StringBuilder(str.length()); StringBuilder sb = new StringBuilder(str.length());
Arrays.sort(pointer);
for (int i = 0; i < pointer.length; i++) { for (int i = 0; i < pointer.length; i++) {
for (int j = 0; j < pointer[i] - (i > 0 ? pointer[i - 1] + 1 : 0); j++) for (int j = 0; j < pointer[i] - (i > 0 ? pointer[i - 1] + 1 : 0); j++)
sb.append(' '); sb.append(' ');

View file

@ -8,40 +8,32 @@ class FormattedSection {
int End; int End;
ArrayList<ChatFormatter> Formatters = new ArrayList<ChatFormatter>(); ArrayList<ChatFormatter> Formatters = new ArrayList<ChatFormatter>();
ArrayList<String> Matches = new ArrayList<String>(); ArrayList<String> Matches = new ArrayList<String>();
short RemCharFromStart;
short RemCharFromEnd;
/** /**
* Is it a 1-long section indicating a start or an end * Is it a 1-long section indicating a start or an end
*/ */
boolean IsRange; boolean IsRange;
FormattedSection(ChatFormatter formatter, int start, int end, ArrayList<String> matches, short remcharfromstart, FormattedSection(ChatFormatter formatter, int start, int end, ArrayList<String> matches, boolean isrange) {
short remcharfromend, boolean isrange) {
Start = start; Start = start;
End = end; End = end;
Formatters.add(formatter); Formatters.add(formatter);
Matches.addAll(matches); Matches.addAll(matches);
RemCharFromStart = remcharfromstart;
RemCharFromEnd = remcharfromend;
IsRange = isrange; IsRange = isrange;
} }
FormattedSection(Collection<ChatFormatter> formatters, int start, int end, ArrayList<String> matches, FormattedSection(Collection<ChatFormatter> formatters, int start, int end, ArrayList<String> matches,
short remcharfromstart, short remcharfromend, boolean isrange) { boolean isrange) {
Start = start; Start = start;
End = end; End = end;
Formatters.addAll(formatters); Formatters.addAll(formatters);
Matches.addAll(matches); Matches.addAll(matches);
RemCharFromStart = remcharfromstart;
RemCharFromEnd = remcharfromend;
IsRange = isrange; IsRange = isrange;
} }
@Override @Override
public String toString() { public String toString() {
return new StringBuilder("Section(").append(Start).append(", ").append(End).append(", formatters: ") return new StringBuilder("Section(").append(Start).append(", ").append(End).append(", formatters: ")
.append(Formatters.toString()).append(", matches: ").append(Matches.toString()).append(", RemChars: ") .append(Formatters.toString()).append(", matches: ").append(Matches.toString()).append(", ")
.append(RemCharFromStart).append(", ").append(RemCharFromEnd).append(", ").append(IsRange).append(")") .append(IsRange).append(")").toString();
.toString();
} }
} }

View file

@ -1,15 +1,5 @@
package buttondevteam.chat.listener; package buttondevteam.chat.listener;
import java.util.Timer;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import com.earth2me.essentials.Essentials;
import buttondevteam.chat.ChatPlayer; import buttondevteam.chat.ChatPlayer;
import buttondevteam.chat.FlairStates; import buttondevteam.chat.FlairStates;
import buttondevteam.chat.PlayerJoinTimerTask; import buttondevteam.chat.PlayerJoinTimerTask;
@ -18,6 +8,22 @@ import buttondevteam.chat.commands.UnlolCommand;
import buttondevteam.lib.player.TBMCPlayerJoinEvent; import buttondevteam.lib.player.TBMCPlayerJoinEvent;
import buttondevteam.lib.player.TBMCPlayerLoadEvent; import buttondevteam.lib.player.TBMCPlayerLoadEvent;
import buttondevteam.lib.player.TBMCPlayerSaveEvent; import buttondevteam.lib.player.TBMCPlayerSaveEvent;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Arrays;
import java.util.Timer;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
public class PlayerJoinLeaveListener implements Listener { public class PlayerJoinLeaveListener implements Listener {
@ -40,15 +46,13 @@ public class PlayerJoinLeaveListener implements Listener {
PlayerJoinTimerTask tt = new PlayerJoinTimerTask() { PlayerJoinTimerTask tt = new PlayerJoinTimerTask() {
@Override @Override
public void run() { public void run() {
p.setPlayerListName(p.getName() + mp.GetFormattedFlair()); mp.FlairUpdate();
} }
}; };
tt.mp = cp; tt.mp = cp;
timer.schedule(tt, 1000); timer.schedule(tt, 1000);
} else { } else {
if (cp.FlairTime().get() == 0x00) /*Timer timer = new Timer();
cp.SetFlair(ChatPlayer.FlairTimeNone);
Timer timer = new Timer();
PlayerJoinTimerTask tt = new PlayerJoinTimerTask() { PlayerJoinTimerTask tt = new PlayerJoinTimerTask() {
@Override @Override
@ -70,10 +74,11 @@ public class PlayerJoinLeaveListener implements Listener {
} }
}; };
tt.mp = cp; tt.mp = cp;
timer.schedule(tt, 15 * 1000); timer.schedule(tt, 15 * 1000);*/ //TODO: Better Reddit integration (OAuth)
} }
String nwithoutformatting = PluginMain.essentials.getUser(p).getNickname(); String nwithoutformatting = PluginMain.essentials.getUser(p).getNickname();
int index; int index;
if (nwithoutformatting != null) { if (nwithoutformatting != null) {
while ((index = nwithoutformatting.indexOf("§k")) != -1) while ((index = nwithoutformatting.indexOf("§k")) != -1)
@ -84,7 +89,9 @@ public class PlayerJoinLeaveListener implements Listener {
nwithoutformatting = p.getName(); nwithoutformatting = p.getName();
PlayerListener.nicknames.put(nwithoutformatting, p.getUniqueId()); PlayerListener.nicknames.put(nwithoutformatting, p.getUniqueId());
cp.FlairUpdate(); Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
updatePlayerColors(p, cp); //TODO: Doesn't have effect
}, 5);
if (cp.ChatOnly || p.getGameMode().equals(GameMode.SPECTATOR)) { if (cp.ChatOnly || p.getGameMode().equals(GameMode.SPECTATOR)) {
cp.ChatOnly = false; cp.ChatOnly = false;
@ -102,4 +109,45 @@ public class PlayerJoinLeaveListener implements Listener {
UnlolCommand.Lastlol.values().removeIf(lld -> lld.getLolowner().equals(event.getPlayer())); UnlolCommand.Lastlol.values().removeIf(lld -> lld.getLolowner().equals(event.getPlayer()));
} }
private static String getPlayerNickname(Player player, User user) {
String nickname = user.getNick(true);
if (nickname.contains("~")) //StartsWith doesn't work because of color codes
nickname = nickname.replace("~", ""); //It gets stacked otherwise
val res = PluginMain.TU.getResidentMap().get(player.getName().toLowerCase());
if (res == null || !res.hasTown())
return nickname;
try {
val clrs = PluginMain.TownColors.get(res.getTown().getName().toLowerCase());
if (clrs == null)
return nickname;
StringBuilder ret = new StringBuilder();
String name = ChatColor.stripColor(nickname);
AtomicInteger prevlen = new AtomicInteger();
BiFunction<Integer, Integer, String> coloredNamePart = (len, i) -> "§"
+ Integer.toHexString(clrs[i].ordinal()) // 'Odds' are the last character is chopped off so we make sure to include all chars at the end
+ (i + 1 == clrs.length ? name.substring(prevlen.get())
: name.substring(prevlen.get(), prevlen.addAndGet(len)));
int len = name.length() / clrs.length;
val nclar = ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class).NameColorLocations().get();
int[] ncl = nclar == null ? null : nclar.stream().mapToInt(Integer::intValue).toArray();
if (ncl != null && (Arrays.stream(ncl).sum() != name.length() || ncl.length != clrs.length))
ncl = null; // Reset if name length changed
for (int i = 0; i < clrs.length; i++)
ret.append(coloredNamePart.apply(ncl == null ? len : ncl[i], i));
return ret.toString();
} catch (NotRegisteredException e) {
return nickname;
}
}
public static void updatePlayerColors(Player player) { //Probably while ingame (/u ncolor)
updatePlayerColors(player, ChatPlayer.getPlayer(player.getUniqueId(), ChatPlayer.class));
}
public static void updatePlayerColors(Player player, ChatPlayer cp) { //Probably at join - nop, nicknames
User user = PluginMain.essentials.getUser(player);
user.setNickname(getPlayerNickname(player, user));
user.setDisplayNick(); //These won't fire the nick change event
cp.FlairUpdate(); //Update in list
}
} }

View file

@ -1,37 +1,40 @@
package buttondevteam.chat.listener; package buttondevteam.chat.listener;
import java.util.*; import buttondevteam.chat.ChatPlayer;
import java.util.Map.Entry; import buttondevteam.chat.ChatProcessing;
import java.util.function.Consumer; import buttondevteam.chat.PluginMain;
import java.util.function.Supplier;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.*;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.help.HelpTopic;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import buttondevteam.chat.*;
import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.ChatChannelRegisterEvent; import buttondevteam.lib.chat.ChatChannelRegisterEvent;
import buttondevteam.lib.chat.ChatRoom; import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerGetInfoEvent; import buttondevteam.lib.player.TBMCPlayerGetInfoEvent;
import net.ess3.api.events.NickChangeEvent;
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.vexsoftware.votifier.model.Vote; import com.vexsoftware.votifier.model.Vote;
import com.vexsoftware.votifier.model.VotifierEvent; import com.vexsoftware.votifier.model.VotifierEvent;
import net.ess3.api.events.NickChangeEvent;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.*;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.help.HelpTopic;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class PlayerListener implements Listener { public class PlayerListener implements Listener {
/** /**
@ -76,7 +79,9 @@ public class PlayerListener implements Listener {
else else
mp = null; mp = null;
String cmd = ""; String cmd = "";
if (index == -1 && (sender instanceof Player || sender instanceof ConsoleCommandSender)) { // Only the command is run if (index == -1) { // Only the command is run
if (!(sender instanceof Player || sender instanceof ConsoleCommandSender))
return false;
// ^^ We can only store player or console channels - Directly sending to channels would still work if they had an event // ^^ We can only store player or console channels - Directly sending to channels would still work if they had an event
cmd = sender instanceof ConsoleCommandSender ? message : message.substring(1); cmd = sender instanceof ConsoleCommandSender ? message : message.substring(1);
for (Channel channel : Channel.getChannels()) { for (Channel channel : Channel.getChannels()) {
@ -109,22 +114,31 @@ public class PlayerListener implements Listener {
if (player != null && sender instanceof Player) if (player != null && sender instanceof Player)
player.sendMessage("§b" + ((Player) sender).getDisplayName() + " §bis in this world: " player.sendMessage("§b" + ((Player) sender).getDisplayName() + " §bis in this world: "
+ ((Player) sender).getWorld().getName()); + ((Player) sender).getWorld().getName());
} else if (cmd.equalsIgnoreCase("minecraft:me")) { } else if (cmd.equalsIgnoreCase("minecraft:me")) {
if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) { if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) {
String msg = message.substring(index + 1); String msg = message.substring(index + 1);
Bukkit.broadcastMessage(String.format("* %s %s", ((Player) sender).getDisplayName(), msg)); Bukkit.broadcastMessage(String.format("* %s %s", sender instanceof Player ? ((Player) sender).getDisplayName() : sender.getName(), msg));
return true; return true;
} else { } else {
sender.sendMessage("§cCan't use /minecraft:me while muted."); sender.sendMessage("§cCan't use /minecraft:me while muted.");
return true; return true;
} }
} else } else if (cmd.equalsIgnoreCase("me")) { //Take over for Discord broadcast
for (Channel channel : Channel.getChannels()) { if (!(sender instanceof Player) || !PluginMain.essentials.getUser((Player) sender).isMuted()) {
if (cmd.equalsIgnoreCase(channel.ID)) { String msg = message.substring(index + 1);
TBMCChatAPI.SendChatMessage(channel, sender, message.substring(index + 1)); Bukkit.broadcastMessage(String.format("§5* %s %s", sender instanceof Player ? ((Player) sender).getDisplayName() : sender.getName(), msg));
return true; return true;
} } else {
} sender.sendMessage("§cCan't use /me while muted.");
return true;
}
} else
for (Channel channel : Channel.getChannels()) {
if (cmd.equalsIgnoreCase(channel.ID)) {
TBMCChatAPI.SendChatMessage(channel, sender, message.substring(index + 1));
return true;
}
}
// TODO: Target selectors // TODO: Target selectors
} }
// We don't care if we have arguments // We don't care if we have arguments
@ -199,7 +213,7 @@ public class PlayerListener implements Listener {
@EventHandler @EventHandler
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void onVotifierEvent(VotifierEvent event) { public void onVotifierEvent(VotifierEvent event) { //TODO: Move to teh Core eh
Vote vote = event.getVote(); Vote vote = event.getVote();
PluginMain.Instance.getLogger().info("Vote: " + vote); PluginMain.Instance.getLogger().info("Vote: " + vote);
org.bukkit.OfflinePlayer op = Bukkit.getOfflinePlayer(vote.getUsername()); org.bukkit.OfflinePlayer op = Bukkit.getOfflinePlayer(vote.getUsername());
@ -278,5 +292,10 @@ public class PlayerListener implements Listener {
@EventHandler @EventHandler
public void onNickChange(NickChangeEvent e) { public void onNickChange(NickChangeEvent e) {
nicknames.inverse().put(e.getAffected().getBase().getUniqueId(), e.getValue()); nicknames.inverse().put(e.getAffected().getBase().getUniqueId(), e.getValue());
//PlayerJoinLeaveListener.updatePlayerColors(e.getAffected().getBase()); //Won't fire this event again
Bukkit.getScheduler().runTaskLater(PluginMain.Instance, () -> {
PlayerJoinLeaveListener.updatePlayerColors(e.getAffected().getBase()); //TODO: Doesn't have effect
}, 1);
} }
} }

View file

@ -28,6 +28,8 @@ commands:
aliases: ww aliases: ww
lenny: lenny:
description: Lenny face. description: Lenny face.
ftop:
description: Top respect.
author: NorbiPeti author: NorbiPeti
depend: depend:
- Essentials - Essentials
@ -42,4 +44,10 @@ permissions:
tbmc.admin: tbmc.admin:
description: Gives access to /un- commands and /u admin commands description: Gives access to /un- commands and /u admin commands
tbmc.rainbow: tbmc.rainbow:
description: Gives access to rainbow colors (/u c). description: Gives access to rainbow colors (/u c).
tbmc.badge.gold:
description: Gives a patron badge.
default: false
tbmc.badge.diamond:
description: Gives a cool patron badge.
default: false

View file

@ -1,5 +1,7 @@
package buttondevteam.chat; package buttondevteam.chat;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -18,10 +20,9 @@ import buttondevteam.chat.formatting.TellrawPart;
import buttondevteam.core.TestPrepare; import buttondevteam.core.TestPrepare;
import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.Color; import buttondevteam.lib.chat.Color;
import junit.framework.TestCase;
@RunWith(ObjectTestRunner.class) @RunWith(ObjectTestRunner.class)
public class ChatFormatIT extends TestCase { public class ChatFormatIT {
@Objects @Objects
public static List<Object> data() { public static List<Object> data() {
TestPrepare.PrepareServer(); TestPrepare.PrepareServer();