diff --git a/Changelog.txt b/Changelog.txt
index 0e4573159..df2f38d3d 100644
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -1,3 +1,13 @@
+Version 2.1.155
+ Optimized party/admin chat a bit
+ Fixed a bug where party members other than the party leader had names that weren't properly hex colored
+ (API) Removed AbstractPlayerAuthor#getComponentDisplayName
+ (API) Removed AbstractPlayerAuthor#getComponentUserName
+ (API) Removed Author#getAuthoredComponentName
+
+ NOTES:
+ Removed some unnecessary API, we aren't a chat plugin so these things shouldn't be here.
+
Version 2.1.154
Hex colors are now supported in Party & Admin chat
Added support for RRGGBB color codes (hex colors) in chat and nicknames for party and admin chat
@@ -6,7 +16,7 @@ Version 2.1.154
Fixed a bug where using admin chat would in some circumstances throw a NPE
(API) Author class has been reworked
(API) McMMOChatEvent::getSender removed (use getDisplayName() instead)
- (API) McMMMOChatEvent::setDisplayName() removed (you can set author names in Author)
+ (API) McMMMOChatEvent::setDisplayName() removed
(API) Removed Author::setName use Player::SetDisplayName instead
(API) Modified Author::getAuthoredName signature to -> Author::getAuthoredName(ChatChannel)
(API) Added Author::getAuthoredComponentName(ChatChannel)
diff --git a/pom.xml b/pom.xml
index 246612928..3b24bfcb2 100755
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
com.gmail.nossr50.mcMMO
mcMMO
- 2.1.154
+ 2.1.155-SNAPSHOT
mcMMO
https://github.com/mcMMO-Dev/mcMMO
diff --git a/src/main/java/com/gmail/nossr50/chat/ChatManager.java b/src/main/java/com/gmail/nossr50/chat/ChatManager.java
index ae6499583..a0a1e6f30 100644
--- a/src/main/java/com/gmail/nossr50/chat/ChatManager.java
+++ b/src/main/java/com/gmail/nossr50/chat/ChatManager.java
@@ -10,6 +10,7 @@ import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.text.StringUtils;
import net.kyori.adventure.audience.Audience;
@@ -39,6 +40,7 @@ public class ChatManager {
/**
* Handles player messaging when they are either in party chat or admin chat modes
+ *
* @param mmoPlayer target player
* @param rawMessage the raw message from the player as it was typed
* @param isAsync whether or not this is getting processed via async
@@ -49,6 +51,7 @@ public class ChatManager {
/**
* Handles player messaging for a specific chat channel
+ *
* @param mmoPlayer target player
* @param args the raw command arguments from the player
* @param chatChannel target channel
@@ -62,6 +65,7 @@ public class ChatManager {
/**
* Handles player messaging for a specific chat channel
+ *
* @param mmoPlayer target player
* @param chatChannel target chat channel
* @param rawMessage raw chat message as it was typed
@@ -73,7 +77,7 @@ public class ChatManager {
adminChatMailer.processChatMessage(mmoPlayer.getPlayerAuthor(), rawMessage, isAsync, Permissions.colorChat(mmoPlayer.getPlayer()));
break;
case PARTY:
- partyChatMailer.processChatMessage(mmoPlayer.getPlayerAuthor(), rawMessage, mmoPlayer.getParty(), isAsync, Permissions.colorChat(mmoPlayer.getPlayer()), isPartyLeader(mmoPlayer));
+ partyChatMailer.processChatMessage(mmoPlayer.getPlayerAuthor(), rawMessage, mmoPlayer.getParty(), isAsync, Permissions.colorChat(mmoPlayer.getPlayer()), Misc.isPartyLeader(mmoPlayer));
break;
case PARTY_OFFICER:
case NONE:
@@ -81,10 +85,6 @@ public class ChatManager {
}
}
- private boolean isPartyLeader(@NotNull McMMOPlayer mmoPlayer) {
- return mmoPlayer.getParty().getLeader().getUniqueId().equals(mmoPlayer.getPlayer().getUniqueId());
- }
-
/**
* Handles console messaging to admins
* @param rawMessage raw message from the console
@@ -221,4 +221,5 @@ public class ChatManager {
}
}
}
+
}
\ No newline at end of file
diff --git a/src/main/java/com/gmail/nossr50/chat/author/AbstractPlayerAuthor.java b/src/main/java/com/gmail/nossr50/chat/author/AbstractPlayerAuthor.java
index 7cc36eee7..e2bb7c7e0 100644
--- a/src/main/java/com/gmail/nossr50/chat/author/AbstractPlayerAuthor.java
+++ b/src/main/java/com/gmail/nossr50/chat/author/AbstractPlayerAuthor.java
@@ -1,64 +1,87 @@
package com.gmail.nossr50.chat.author;
+import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.util.text.TextUtils;
import com.google.common.base.Objects;
-import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import java.util.HashMap;
import java.util.UUID;
public abstract class AbstractPlayerAuthor implements Author {
private final @NotNull Player player;
- private @NotNull String displayName;
- private @Nullable TextComponent componentDisplayName;
- private @Nullable TextComponent componentUserName;
+ private @NotNull String lastKnownDisplayName;
+ private final @NotNull HashMap sanitizedNameCache;
public AbstractPlayerAuthor(@NotNull Player player) {
this.player = player;
- this.displayName = player.getDisplayName();
+ this.lastKnownDisplayName = player.getDisplayName();
+ this.sanitizedNameCache = new HashMap<>();
}
/**
- * Grabs the {@link TextComponent} version of a players display name
- * Cached and only processed as needed
- * Always checks if the player display name has changed, if it has it regenerates the output
+ * Returns true if a players display name has changed
*
- * @return the {@link TextComponent} version of a players display name
+ * @return true if the players display name has changed
*/
- public @NotNull TextComponent getComponentDisplayName() {
- //Not sure if this is expensive but it ensures always up to date names
- if(!player.getDisplayName().equals(displayName)) {
- displayName = player.getDisplayName();
- componentDisplayName = null;
- }
-
- if(componentDisplayName != null) {
- return componentDisplayName;
- } else {
- //convert to adventure component
- componentDisplayName = TextUtils.ofLegacyTextRaw(displayName);
- }
- return componentDisplayName;
+ private boolean hasPlayerDisplayNameChanged() {
+ return !player.getDisplayName().equals(lastKnownDisplayName);
}
/**
- * Grabs the {@link TextComponent} version of a players current minecraft nickname
- * Cached and only processed as needed
- *
- * @return the {@link TextComponent} version of a players current minecraft nickname
+ * Player display names can change and this method will update the last known display name of this player
*/
- public @NotNull TextComponent getComponentUserName() {
- //Not sure if this is expensive but it ensures always up to date names
- if(componentUserName != null) {
- return componentUserName;
+ private void updateLastKnownDisplayName() {
+ lastKnownDisplayName = player.getDisplayName();
+ }
+
+ /**
+ * Gets a sanitized name for a channel
+ * Sanitized names are names that are friendly to the {@link net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer}
+ * Sanitized names for authors are cached by channel and are only created as needed
+ * Sanitized names will update if a players display name has updated
+ *
+ * @param chatChannel target chat channel
+ * @return the sanitized name for a player
+ */
+ protected @NotNull String getSanitizedName(@NotNull ChatChannel chatChannel, boolean useDisplayName) {
+ //Already in cache
+ if(sanitizedNameCache.containsKey(chatChannel)) {
+ //Update cache
+ if(useDisplayName && hasPlayerDisplayNameChanged()) {
+ updateLastKnownDisplayName();
+ updateSanitizedNameCache(chatChannel, true);
+ }
} else {
- //convert to adventure component
- componentUserName = TextUtils.ofLegacyTextRaw(player.getName());
+ //Update last known display name
+ if(useDisplayName && hasPlayerDisplayNameChanged()) {
+ updateLastKnownDisplayName();
+ }
+
+ //Add cache entry
+ updateSanitizedNameCache(chatChannel, useDisplayName);
+ }
+
+ return sanitizedNameCache.get(chatChannel);
+ }
+
+ /**
+ * Update the sanitized name cache
+ * This will add entries if one didn't exit
+ * Sanitized names are associated with a {@link ChatChannel} as different chat channels have different chat name settings
+ *
+ * @param chatChannel target chat channel
+ * @param useDisplayName whether or not to use this authors display name
+ */
+ private void updateSanitizedNameCache(@NotNull ChatChannel chatChannel, boolean useDisplayName) {
+ if(useDisplayName) {
+ sanitizedNameCache.put(chatChannel, TextUtils.sanitizeForSerializer(player.getDisplayName()));
+ } else {
+ //No need to sanitize a basic String
+ sanitizedNameCache.put(chatChannel, player.getName());
}
- return componentUserName;
}
@Override
@@ -85,11 +108,13 @@ public abstract class AbstractPlayerAuthor implements Author {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AbstractPlayerAuthor that = (AbstractPlayerAuthor) o;
- return Objects.equal(player, that.player);
+ return Objects.equal(player, that.player) &&
+ Objects.equal(lastKnownDisplayName, that.lastKnownDisplayName) &&
+ Objects.equal(sanitizedNameCache, that.sanitizedNameCache);
}
@Override
public int hashCode() {
- return Objects.hashCode(player);
+ return Objects.hashCode(player, lastKnownDisplayName, sanitizedNameCache);
}
}
diff --git a/src/main/java/com/gmail/nossr50/chat/author/Author.java b/src/main/java/com/gmail/nossr50/chat/author/Author.java
index 36977b99e..6f45a21b7 100644
--- a/src/main/java/com/gmail/nossr50/chat/author/Author.java
+++ b/src/main/java/com/gmail/nossr50/chat/author/Author.java
@@ -2,25 +2,10 @@ package com.gmail.nossr50.chat.author;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
import net.kyori.adventure.identity.Identity;
-import net.kyori.adventure.text.TextComponent;
import org.jetbrains.annotations.NotNull;
public interface Author extends Identity {
- /**
- * The name of this author as used in mcMMO chat
- * This is the {@link TextComponent} representation of the users current chat username
- * This can either be the player's display name or the player's official registered nickname with Mojang it depends on the servers chat settings for mcMMO
- *
- * NOTE:
- * mcMMO doesn't transform a players name into a component when creating the chat message, instead it converts the whole string from raw legacy text (including md5 stuff) -> TextComponent via {@link net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer}
- * This method is just provided for convenience, it uses lazy initialization
- *
- * @param chatChannel which chat channel this is going to
- * @return The name of this author as used in mcMMO chat
- */
- @NotNull TextComponent getAuthoredComponentName(@NotNull ChatChannel chatChannel);
-
/**
* The name of this author as used in mcMMO chat
* This is the {@link String} representation of the users current chat username
diff --git a/src/main/java/com/gmail/nossr50/chat/author/ConsoleAuthor.java b/src/main/java/com/gmail/nossr50/chat/author/ConsoleAuthor.java
index 978b5d544..3c6452d32 100644
--- a/src/main/java/com/gmail/nossr50/chat/author/ConsoleAuthor.java
+++ b/src/main/java/com/gmail/nossr50/chat/author/ConsoleAuthor.java
@@ -2,7 +2,6 @@ package com.gmail.nossr50.chat.author;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.util.text.TextUtils;
-import net.kyori.adventure.text.TextComponent;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull;
@@ -11,20 +10,13 @@ import java.util.UUID;
public class ConsoleAuthor implements Author {
private final UUID uuid;
private final @NotNull String name;
- private final @NotNull TextComponent componentName;
public ConsoleAuthor(@NotNull String name) {
this.uuid = new UUID(0, 0);
- this.name = name;
- this.componentName = TextUtils.ofBungeeRawStrings(name);
- }
-
- //TODO: Think of a better solution later
- @Override
- public @NotNull TextComponent getAuthoredComponentName(@NotNull ChatChannel chatChannel) {
- return componentName;
+ this.name = TextUtils.sanitizeForSerializer(name);
}
+ //TODO: Think of a less clunky solution later
@Override
public @NotNull String getAuthoredName(@NotNull ChatChannel chatChannel) {
return name;
diff --git a/src/main/java/com/gmail/nossr50/chat/author/PlayerAuthor.java b/src/main/java/com/gmail/nossr50/chat/author/PlayerAuthor.java
index 1921faaed..72383e96e 100644
--- a/src/main/java/com/gmail/nossr50/chat/author/PlayerAuthor.java
+++ b/src/main/java/com/gmail/nossr50/chat/author/PlayerAuthor.java
@@ -2,7 +2,6 @@ package com.gmail.nossr50.chat.author;
import com.gmail.nossr50.config.ChatConfig;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
-import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -12,22 +11,9 @@ public class PlayerAuthor extends AbstractPlayerAuthor {
super(player);
}
- @Override
- public @NotNull TextComponent getAuthoredComponentName(@NotNull ChatChannel chatChannel) {
- if(ChatConfig.getInstance().useDisplayNames(chatChannel)) {
- return getComponentDisplayName();
- } else {
- return getComponentUserName();
- }
- }
-
@Override
public @NotNull String getAuthoredName(@NotNull ChatChannel chatChannel) {
- if(ChatConfig.getInstance().useDisplayNames(chatChannel)) {
- return getPlayer().getDisplayName();
- } else {
- return getPlayer().getName();
- }
+ return getSanitizedName(chatChannel, ChatConfig.getInstance().useDisplayNames(chatChannel));
}
}
diff --git a/src/main/java/com/gmail/nossr50/chat/mailer/AdminChatMailer.java b/src/main/java/com/gmail/nossr50/chat/mailer/AdminChatMailer.java
index a238d4e63..de922e56a 100644
--- a/src/main/java/com/gmail/nossr50/chat/mailer/AdminChatMailer.java
+++ b/src/main/java/com/gmail/nossr50/chat/mailer/AdminChatMailer.java
@@ -29,6 +29,7 @@ public class AdminChatMailer extends AbstractChatMailer {
/**
* Constructs an audience of admins
+ *
* @return an audience of admins
*/
public @NotNull Audience constructAudience() {
@@ -37,6 +38,7 @@ public class AdminChatMailer extends AbstractChatMailer {
/**
* Predicate used to filter the audience
+ *
* @return admin chat audience predicate
*/
public @NotNull Predicate predicate() {
@@ -47,6 +49,7 @@ public class AdminChatMailer extends AbstractChatMailer {
/**
* Styles a string using a locale entry
+ *
* @param author message author
* @param message message contents
* @param canColor whether to replace colors codes with colors in the raw message
@@ -54,7 +57,7 @@ public class AdminChatMailer extends AbstractChatMailer {
*/
public @NotNull TextComponent addStyle(@NotNull Author author, @NotNull String message, boolean canColor) {
if(canColor) {
- return LocaleLoader.getTextComponent("Chat.Style.Admin", TextUtils.sanitizeAuthorName(author, ChatChannel.ADMIN), message);
+ return LocaleLoader.getTextComponent("Chat.Style.Admin", author.getAuthoredName(ChatChannel.ADMIN), message);
} else {
return TextUtils.ofLegacyTextRaw(LocaleLoader.getString("Chat.Style.Admin", author.getAuthoredName(ChatChannel.ADMIN), message));
}
@@ -65,6 +68,14 @@ public class AdminChatMailer extends AbstractChatMailer {
chatMessage.sendMessage();
}
+ /**
+ * Processes a chat message from an author to an audience of admins
+ *
+ * @param author the author
+ * @param rawString the raw message as the author typed it before any styling
+ * @param isAsync whether or not this is being processed asynchronously
+ * @param canColor whether or not the author can use colors in chat
+ */
public void processChatMessage(@NotNull Author author, @NotNull String rawString, boolean isAsync, boolean canColor) {
AdminChatMessage chatMessage = new AdminChatMessage(pluginRef, author, constructAudience(), rawString, addStyle(author, rawString, canColor));
@@ -77,4 +88,4 @@ public class AdminChatMailer extends AbstractChatMailer {
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gmail/nossr50/chat/mailer/PartyChatMailer.java b/src/main/java/com/gmail/nossr50/chat/mailer/PartyChatMailer.java
index 37c02f144..6158ad826 100644
--- a/src/main/java/com/gmail/nossr50/chat/mailer/PartyChatMailer.java
+++ b/src/main/java/com/gmail/nossr50/chat/mailer/PartyChatMailer.java
@@ -22,6 +22,14 @@ public class PartyChatMailer extends AbstractChatMailer {
super(pluginRef);
}
+ /**
+ * Processes a chat message from an author to an audience of party members
+ *
+ * @param author the author
+ * @param rawString the raw message as the author typed it before any styling
+ * @param isAsync whether or not this is being processed asynchronously
+ * @param canColor whether or not the author can use colors in chat
+ */
public void processChatMessage(@NotNull Author author, @NotNull String rawString, @NotNull Party party, boolean isAsync, boolean canColor, boolean isLeader) {
PartyChatMessage chatMessage = new PartyChatMessage(pluginRef, author, constructPartyAudience(party), rawString, addStyle(author, rawString, canColor, isLeader), party);
@@ -33,12 +41,19 @@ public class PartyChatMailer extends AbstractChatMailer {
}
}
+ /**
+ * Constructs an {@link Audience} of party members
+ *
+ * @param party target party
+ * @return an {@link Audience} of party members
+ */
public @NotNull Audience constructPartyAudience(@NotNull Party party) {
return mcMMO.getAudiences().filter(party.getSamePartyPredicate());
}
/**
* Styles a string using a locale entry
+ *
* @param author message author
* @param message message contents
* @param canColor whether to replace colors codes with colors in the raw message
@@ -47,7 +62,7 @@ public class PartyChatMailer extends AbstractChatMailer {
public @NotNull TextComponent addStyle(@NotNull Author author, @NotNull String message, boolean canColor, boolean isLeader) {
if(canColor) {
if(isLeader) {
- return LocaleLoader.getTextComponent("Chat.Style.Party.Leader", TextUtils.sanitizeAuthorName(author, ChatChannel.PARTY), message);
+ return LocaleLoader.getTextComponent("Chat.Style.Party.Leader", author.getAuthoredName(ChatChannel.PARTY), message);
} else {
return LocaleLoader.getTextComponent("Chat.Style.Party", author.getAuthoredName(ChatChannel.PARTY), message);
}
diff --git a/src/main/java/com/gmail/nossr50/chat/message/PartyChatMessage.java b/src/main/java/com/gmail/nossr50/chat/message/PartyChatMessage.java
index c66644d6e..4c143ec69 100644
--- a/src/main/java/com/gmail/nossr50/chat/message/PartyChatMessage.java
+++ b/src/main/java/com/gmail/nossr50/chat/message/PartyChatMessage.java
@@ -7,7 +7,6 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
-import com.gmail.nossr50.util.text.TextUtils;
import com.google.common.base.Objects;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.TextComponent;
@@ -46,7 +45,7 @@ public class PartyChatMessage extends AbstractChatMessage {
//Sends to everyone but console
audience.sendMessage(author, componentMessage);
- TextComponent spyMessage = LocaleLoader.getTextComponent("Chat.Spy.Party", TextUtils.sanitizeAuthorName(author, ChatChannel.PARTY), rawMessage, party.getName());
+ TextComponent spyMessage = LocaleLoader.getTextComponent("Chat.Spy.Party", author.getAuthoredName(ChatChannel.PARTY), rawMessage, party.getName());
//Relay to spies
messagePartyChatSpies(spyMessage);
diff --git a/src/main/java/com/gmail/nossr50/util/Misc.java b/src/main/java/com/gmail/nossr50/util/Misc.java
index 92316d732..41195c08d 100644
--- a/src/main/java/com/gmail/nossr50/util/Misc.java
+++ b/src/main/java/com/gmail/nossr50/util/Misc.java
@@ -1,6 +1,7 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.api.ItemSpawnReason;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
@@ -299,4 +300,14 @@ public final class Misc {
public static @NotNull Random getRandom() {
return random;
}
+
+ /**
+ * Whether or not a player is the party leader of a party
+ *
+ * @param mmoPlayer target player
+ * @return true if the player is the party leader
+ */
+ public static boolean isPartyLeader(@NotNull McMMOPlayer mmoPlayer) {
+ return mmoPlayer.getParty().getLeader().getUniqueId().equals(mmoPlayer.getPlayer().getUniqueId());
+ }
}
diff --git a/src/main/java/com/gmail/nossr50/util/text/TextUtils.java b/src/main/java/com/gmail/nossr50/util/text/TextUtils.java
index 231b7be69..1f1b24c2c 100644
--- a/src/main/java/com/gmail/nossr50/util/text/TextUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/text/TextUtils.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.util.text;
-import com.gmail.nossr50.chat.author.Author;
-import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.mcMMO;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder;
@@ -130,8 +128,4 @@ public class TextUtils {
TextComponent componentForm = ofLegacyTextRaw(string);
return customLegacySerializer.serialize(componentForm);
}
-
- public static @NotNull String sanitizeAuthorName(@NotNull Author author, @NotNull ChatChannel chatChannel) {
- return sanitizeForSerializer(author.getAuthoredName(ChatChannel.ADMIN));
- }
}