Better party chat logging in console, some style changes to admin/party chat as well

This commit is contained in:
nossr50 2020-10-27 13:09:01 -07:00
parent d183d1217c
commit 2f506b72bb
14 changed files with 144 additions and 48 deletions

View File

@ -4,6 +4,7 @@ Version 2.1.150
Players & Console can now use color codes (including stuff like &a or [[GREEN]]) in party or admin chat Players & Console can now use color codes (including stuff like &a or [[GREEN]]) in party or admin chat
Added new permission node 'mcmmo.chat.colors' which allows players to use color codes, negate to disallow this Added new permission node 'mcmmo.chat.colors' which allows players to use color codes, negate to disallow this
The style and look of admin/party chat is now determined by locale file instead of options in config.yml The style and look of admin/party chat is now determined by locale file instead of options in config.yml
The default style of admin/party chat has been updated, and it may be updated again in the future
Improved messages players recieve when they toggle on or off admin or party chat Improved messages players recieve when they toggle on or off admin or party chat
All locale files have had [[]] color codes replaced by & color codes, you can still use [[GOLD]] and stuff if you want All locale files have had [[]] color codes replaced by & color codes, you can still use [[GOLD]] and stuff if you want
You can now add "-s" at the end of mmoedit, addlevels, or addxp to silence the command. Which will prevent the target of the command from being informed that the command was executed. You can now add "-s" at the end of mmoedit, addlevels, or addxp to silence the command. Which will prevent the target of the command from being informed that the command was executed.

View File

@ -11,8 +11,10 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.StringUtils;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.command.ConsoleCommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
//TODO: Micro optimization - Cache audiences and update cache when needed //TODO: Micro optimization - Cache audiences and update cache when needed
public class ChatManager { public class ChatManager {
@ -20,11 +22,15 @@ public class ChatManager {
private final @NotNull AdminChatMailer adminChatMailer; private final @NotNull AdminChatMailer adminChatMailer;
private final @NotNull PartyChatMailer partyChatMailer; private final @NotNull PartyChatMailer partyChatMailer;
private @Nullable ConsoleAuthor consoleAuthor; private final @NotNull ConsoleAuthor consoleAuthor;
private final @NotNull Audience consoleAudience;
public ChatManager(@NotNull mcMMO pluginRef) { public ChatManager(@NotNull mcMMO pluginRef) {
adminChatMailer = new AdminChatMailer(pluginRef); adminChatMailer = new AdminChatMailer(pluginRef);
partyChatMailer = new PartyChatMailer(pluginRef); partyChatMailer = new PartyChatMailer(pluginRef);
this.consoleAuthor = new ConsoleAuthor(LocaleLoader.getString("Chat.Identity.Console"));
this.consoleAudience = mcMMO.getAudiences().filter((cs) -> cs instanceof ConsoleCommandSender);
} }
/** /**
@ -96,27 +102,11 @@ public class ChatManager {
partyChatMailer.processChatMessage(getConsoleAuthor(), rawMessage, party, false, true); partyChatMailer.processChatMessage(getConsoleAuthor(), rawMessage, party, false, true);
} }
/**
* Handles console messaging to a specific party
* @param args raw command args from the console
* @param party target party
*/
public void processConsoleMessage(@NotNull String[] args, @NotNull Party party) {
String chatMessageWithoutCommand = buildChatMessage(args);
processConsoleMessage(chatMessageWithoutCommand, party);
}
/** /**
* Gets a console author * Gets a console author
* Constructs one if it doesn't already exist
* @return a {@link ConsoleAuthor} * @return a {@link ConsoleAuthor}
*/ */
private @NotNull Author getConsoleAuthor() { private @NotNull Author getConsoleAuthor() {
if (consoleAuthor == null) {
consoleAuthor = new ConsoleAuthor(LocaleLoader.getString("Chat.Identity.Console"));
}
return consoleAuthor; return consoleAuthor;
} }
@ -180,5 +170,14 @@ public class ChatManager {
return false; return false;
} }
/**
* Sends just the console a message
* @param author author of the message
* @param message message contents in component form
*/
public void sendConsoleMessage(@NotNull Author author, @NotNull TextComponent message) {
consoleAudience.sendMessage(author, message);
}
} }

View File

@ -21,7 +21,7 @@ public class SamePartyPredicate<T extends CommandSender> implements Predicate<T>
public boolean test(T t) { public boolean test(T t) {
//Include the console in the audience //Include the console in the audience
if(t instanceof ConsoleCommandSender) { if(t instanceof ConsoleCommandSender) {
return true; return false; //Party audiences are special, we exclude console from them to avoid double messaging since we send a more verbose version to consoles
} else { } else {
if(t instanceof Player) { if(t instanceof Player) {
Player player = (Player) t; Player player = (Player) t;

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.chat.author; package com.gmail.nossr50.chat.author;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.google.common.base.Objects;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -38,7 +39,10 @@ public class AdminAuthor implements Author {
return overrideName; return overrideName;
} }
@Override /**
* Set the name of this author
* @param newName value of the new name
*/
public void setName(@NotNull String newName) { public void setName(@NotNull String newName) {
overrideName = newName; overrideName = newName;
} }
@ -57,4 +61,18 @@ public class AdminAuthor implements Author {
public @NonNull UUID uuid() { public @NonNull UUID uuid() {
return player.getUniqueId(); return player.getUniqueId();
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AdminAuthor that = (AdminAuthor) o;
return Objects.equal(player, that.player) &&
Objects.equal(overrideName, that.overrideName);
}
@Override
public int hashCode() {
return Objects.hashCode(player, overrideName);
}
} }

View File

@ -11,12 +11,6 @@ public interface Author extends Identity {
*/ */
@NotNull String getAuthoredName(); @NotNull String getAuthoredName();
/**
* Set the name of this author
* @param newName value of the new name
*/
void setName(@NotNull String newName);
/** /**
* Whether or not this author is a {@link org.bukkit.command.ConsoleCommandSender} * Whether or not this author is a {@link org.bukkit.command.ConsoleCommandSender}
* *

View File

@ -7,7 +7,7 @@ import java.util.UUID;
public class ConsoleAuthor implements Author { public class ConsoleAuthor implements Author {
private final UUID uuid; private final UUID uuid;
private @NotNull String name; private final @NotNull String name;
public ConsoleAuthor(@NotNull String name) { public ConsoleAuthor(@NotNull String name) {
this.name = name; this.name = name;
@ -19,11 +19,6 @@ public class ConsoleAuthor implements Author {
return name; return name;
} }
@Override
public void setName(@NotNull String newName) {
this.name = newName;
}
@Override @Override
public boolean isConsole() { public boolean isConsole() {
return true; return true;

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.chat.author; package com.gmail.nossr50.chat.author;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.google.common.base.Objects;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -30,7 +31,10 @@ public class PartyAuthor implements Author {
} }
} }
@Override /**
* Set the name of this author
* @param newName value of the new name
*/
public void setName(@NotNull String newName) { public void setName(@NotNull String newName) {
overrideName = newName; overrideName = newName;
} }
@ -45,8 +49,26 @@ public class PartyAuthor implements Author {
return true; return true;
} }
public Player getPlayer() {
return player;
}
@Override @Override
public @NonNull UUID uuid() { public @NonNull UUID uuid() {
return player.getUniqueId(); return player.getUniqueId();
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PartyAuthor that = (PartyAuthor) o;
return Objects.equal(player, that.player) &&
Objects.equal(overrideName, that.overrideName);
}
@Override
public int hashCode() {
return Objects.hashCode(player, overrideName);
}
} }

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.chat.message; package com.gmail.nossr50.chat.message;
import com.gmail.nossr50.chat.author.Author; import com.gmail.nossr50.chat.author.Author;
import com.google.common.base.Objects;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -56,4 +57,21 @@ public abstract class AbstractChatMessage implements ChatMessage {
public void setAudience(@NotNull Audience newAudience) { public void setAudience(@NotNull Audience newAudience) {
audience = newAudience; audience = newAudience;
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AbstractChatMessage that = (AbstractChatMessage) o;
return Objects.equal(pluginRef, that.pluginRef) &&
Objects.equal(author, that.author) &&
Objects.equal(rawMessage, that.rawMessage) &&
Objects.equal(componentMessage, that.componentMessage) &&
Objects.equal(audience, that.audience);
}
@Override
public int hashCode() {
return Objects.hashCode(pluginRef, author, rawMessage, componentMessage, audience);
}
} }

View File

@ -3,8 +3,10 @@ package com.gmail.nossr50.chat.message;
import com.gmail.nossr50.chat.author.Author; import com.gmail.nossr50.chat.author.Author;
import com.gmail.nossr50.datatypes.party.Party; import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.google.common.base.Objects;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
@ -31,18 +33,28 @@ public class PartyChatMessage extends AbstractChatMessage {
@Override @Override
public void sendMessage() { public void sendMessage() {
/*
* It should be noted that Party messages don't include console as part of the audience to avoid double messaging
* The console gets a message that has the party name included, player parties do not
*/
//Sends to everyone but console
audience.sendMessage(author, componentMessage); audience.sendMessage(author, componentMessage);
TextComponent spyMessage = Component.text(LocaleLoader.getString("Chat.Spy.Party", author.getAuthoredName(), rawMessage, party.getName()));
//Relay to spies //Relay to spies
TextComponent textComponent = Component.text("[" + getParty().getName() + "] ->" ).append(getChatMessage()); messagePartyChatSpies(spyMessage);
relayChatToSpies(textComponent);
//Console message
mcMMO.p.getChatManager().sendConsoleMessage(author, spyMessage);
} }
/** /**
* Console and Party Chat Spies get a more verbose version of the message
* Party Chat Spies will get a copy of the message as well * Party Chat Spies will get a copy of the message as well
* @param spyMessage the message to copy to spies * @param spyMessage the message to copy to spies
*/ */
private void relayChatToSpies(@NotNull TextComponent spyMessage) { private void messagePartyChatSpies(@NotNull TextComponent spyMessage) {
//Find the people with permissions //Find the people with permissions
for(McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) { for(McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) {
Player player = mcMMOPlayer.getPlayer(); Player player = mcMMOPlayer.getPlayer();
@ -60,4 +72,18 @@ public class PartyChatMessage extends AbstractChatMessage {
} }
} }
} }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
PartyChatMessage that = (PartyChatMessage) o;
return Objects.equal(party, that.party);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), party);
}
} }

View File

@ -12,7 +12,7 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@CommandAlias("a|adminchat") //Kept for historical reasons @CommandAlias("a|adminchat|achat") //Kept for historical reasons
public class AdminChatCommand extends BaseCommand { public class AdminChatCommand extends BaseCommand {
private final @NotNull mcMMO pluginRef; private final @NotNull mcMMO pluginRef;

View File

@ -11,11 +11,12 @@ import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@CommandAlias("p|partychat") //Kept for historical reasons @CommandAlias("p|partychat|pchat") //Kept for historical reasons
public class PartyChatCommand extends BaseCommand { public class PartyChatCommand extends BaseCommand {
private final @NotNull mcMMO pluginRef; private final @NotNull mcMMO pluginRef;
@ -78,7 +79,7 @@ public class PartyChatCommand extends BaseCommand {
Party targetParty = PartyManager.getParty(args[0]); Party targetParty = PartyManager.getParty(args[0]);
if(targetParty != null) { if(targetParty != null) {
pluginRef.getChatManager().processConsoleMessage(args, targetParty); pluginRef.getChatManager().processConsoleMessage(StringUtils.buildStringAfterNthElement(args, 1), targetParty);
} else { } else {
mcMMO.p.getLogger().severe("A party with that name doesn't exist!"); mcMMO.p.getLogger().severe("A party with that name doesn't exist!");
} }

View File

@ -50,14 +50,14 @@ public class ArcheryManager extends SkillManager {
* Calculate bonus XP awarded for Archery when hitting a far-away target. * Calculate bonus XP awarded for Archery when hitting a far-away target.
* *
* @param target The {@link LivingEntity} damaged by the arrow * @param target The {@link LivingEntity} damaged by the arrow
* @param damager The {@link Entity} who shot the arrow * @param arrow The {@link Entity} who shot the arrow
*/ */
public double distanceXpBonusMultiplier(LivingEntity target, Entity damager) { public double distanceXpBonusMultiplier(LivingEntity target, Entity arrow) {
//Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
if(!damager.hasMetadata(mcMMO.arrowDistanceKey)) if(!arrow.hasMetadata(mcMMO.arrowDistanceKey))
return damager.getLocation().distance(target.getLocation()); return arrow.getLocation().distance(target.getLocation());
Location firedLocation = (Location) damager.getMetadata(mcMMO.arrowDistanceKey).get(0).value(); Location firedLocation = (Location) arrow.getMetadata(mcMMO.arrowDistanceKey).get(0).value();
Location targetLocation = target.getLocation(); Location targetLocation = target.getLocation();
if (firedLocation.getWorld() != targetLocation.getWorld()) { if (firedLocation.getWorld() != targetLocation.getWorld()) {

View File

@ -6,6 +6,7 @@ import org.bukkit.Material;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
import java.util.Locale; import java.util.Locale;
@ -22,6 +23,25 @@ public class StringUtils {
return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase(Locale.ENGLISH); return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase(Locale.ENGLISH);
} }
/**
* Creates a string from an array skipping the first n elements
* @param args the array to iterate over when forming the string
* @param index the amount of elements to skip over
* @return the "trimmed" string
*/
public static String buildStringAfterNthElement(@NotNull String @NotNull []args, int index) {
StringBuilder trimMessage = new StringBuilder();
for (int i = index; i < args.length; i++) {
if(i + 1 >= args.length)
trimMessage.append(args[i]);
else
trimMessage.append(args[i]).append(" ");
}
return trimMessage.toString();
}
public static String getPrettyItemString(Material material) { public static String getPrettyItemString(Material material) {
return createPrettyString(material.toString()); return createPrettyString(material.toString());
} }

View File

@ -1117,8 +1117,10 @@ Commands.Description.mmocompat=Information about mcMMO and whether or not its in
Compatibility.Layer.Unsupported=&6Compatibility for &a{0}&6 is not supported by this version of Minecraft. Compatibility.Layer.Unsupported=&6Compatibility for &a{0}&6 is not supported by this version of Minecraft.
Compatibility.Layer.PartialSupport=&6Compatibility for &a{0}&6 is not fully supported by this version of Minecraft, but mcMMO is running a secondary system to emulate some of the missing features. Compatibility.Layer.PartialSupport=&6Compatibility for &a{0}&6 is not fully supported by this version of Minecraft, but mcMMO is running a secondary system to emulate some of the missing features.
Commands.XPBar.DisableAll=&6 All mcMMO XP bars are now disabled, use /mmoxpbar reset to restore default settings. Commands.XPBar.DisableAll=&6 All mcMMO XP bars are now disabled, use /mmoxpbar reset to restore default settings.
Chat.Style.Admin=&b[&f{0}&b] {1} #Modern Chat Settings
Chat.Style.Party=&a[&6{0}&a] {1} Chat.Style.Admin=&b(A) &r{0} &b\u2192 &r{1}
Chat.Identity.Console=* Console * Chat.Style.Party=&a(P) &r{0} &a\u2192 &r{1}
Chat.Identity.Console=&6* Console *
Chat.Channel.On=&6(&amcMMO-Chat&6) &eYour chat messages will now be automatically delivered to the &a{0}&e chat channel. Chat.Channel.On=&6(&amcMMO-Chat&6) &eYour chat messages will now be automatically delivered to the &a{0}&e chat channel.
Chat.Channel.Off=&6(&amcMMO-Chat&6) &7Your chat messages will no longer be automatically delivered to specific chat channels. Chat.Channel.Off=&6(&amcMMO-Chat&6) &7Your chat messages will no longer be automatically delivered to specific chat channels.
Chat.Spy.Party=&6[&eSPY&6-&a{2}&6] &r{0} &b\u2192 &r{1}