Allow toggling public broadcast of AFK messages (#2780)

(description from #2608)

So... I've implemented a system for toggling whether or not AFK messages are broadcasted to the entire server and also changed a few things along the way:

1. I added a config toggle broadcast-afk-message that will change whether AFK messages are broadcast globally or not.
2. In both cases the AFK target now recieves a "self-oriented" message instead of the global default. Basically just says "You are now/no longer AFK". This would be a change from the default behaviour.
3. I created a way to exclude certain IUsers from broadcastMessage messages using an IUser... varargs parameter. I wasn't too sure how to implement the exclusion, but this seemed like a fairly good option.

I'm not too sure if what I've come up with is an optimal solution, but it's been tested and confirmed to work as intended.

closes #2116, closes #959

---

* implement toggle for broadcasting afk message

* add "self-private" AFK messages, implement exclusion system for broadcastMessage

* remove rogue import, clarify config comment

* move excluded collection creation out of loop, use set instead

* use set instead of varargs

* ok but actually use the set this time

* address requested changes

* update missed message section

* move from Collection to Predicate for broadcast exclusion

* update Predicate variable name

* use identity comparison (cleanup)

* clean up unnecessary imports, remove extra spacing
This commit is contained in:
triagonal 2020-04-13 23:33:37 +10:00 committed by GitHub
parent 5082badca4
commit 6f61010cf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 21 deletions

View file

@ -34,14 +34,6 @@ import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.base.Throwables;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import net.ess3.api.IEssentials;
import net.ess3.api.ISettings;
import net.ess3.api.*;
@ -83,6 +75,16 @@ import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import org.yaml.snakeyaml.error.YAMLException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import static com.earth2me.essentials.I18n.tl;
@ -762,20 +764,25 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
@Override
public int broadcastMessage(final String message) {
return broadcastMessage(null, null, message, true);
return broadcastMessage(null, null, message, true, u -> false);
}
@Override
public int broadcastMessage(final IUser sender, final String message) {
return broadcastMessage(sender, null, message, false);
return broadcastMessage(sender, null, message, false, u -> false);
}
@Override
public int broadcastMessage(final IUser sender, final String message, final Predicate<IUser> shouldExclude) {
return broadcastMessage(sender, null, message, false, shouldExclude);
}
@Override
public int broadcastMessage(final String permission, final String message) {
return broadcastMessage(null, permission, message, false);
return broadcastMessage(null, permission, message, false, u -> false);
}
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords) {
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords, final Predicate<IUser> shouldExclude) {
if (sender != null && sender.isHidden()) {
return 0;
}
@ -783,10 +790,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
IText broadcast = new SimpleTextInput(message);
final Collection<Player> players = getOnlinePlayers();
for (Player player : players) {
final User user = getUser(player);
if ((permission == null && (sender == null || !user.isIgnoredPlayer(sender))) || (permission != null && user.isAuthorized(permission))) {
if (shouldExclude.test(user)) {
continue;
}
if (keywords) {
broadcast = new KeywordReplacer(broadcast, new CommandSource(player), this, false);
}

View file

@ -18,6 +18,7 @@ import org.bukkit.scheduler.BukkitTask;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.function.Predicate;
public interface IEssentials extends Plugin {
void addReloadListener(IConf listener);
@ -47,6 +48,8 @@ public interface IEssentials extends Plugin {
int broadcastMessage(IUser sender, String message);
int broadcastMessage(IUser sender, String message, Predicate<IUser> shouldExclude);
int broadcastMessage(String permission, String message);
ISettings getSettings();

View file

@ -196,6 +196,8 @@ public interface ISettings extends IConf {
String getAfkListName();
boolean broadcastAfkMessage();
boolean areDeathMessagesEnabled();
void setDebug(boolean debug);

View file

@ -513,6 +513,7 @@ public class Settings implements net.ess3.api.ISettings {
sleepIgnoresAfkPlayers = _sleepIgnoresAfkPlayers();
afkListName = _getAfkListName();
isAfkListName = !afkListName.equalsIgnoreCase("none");
broadcastAfkMessage = _broadcastAfkMessage();
itemSpawnBl = _getItemSpawnBlacklist();
loginAttackDelay = _getLoginAttackDelay();
signUsePerSecond = _getSignUsePerSecond();
@ -949,6 +950,17 @@ public class Settings implements net.ess3.api.ISettings {
return afkListName;
}
private boolean broadcastAfkMessage;
@Override
public boolean broadcastAfkMessage() {
return broadcastAfkMessage;
}
private boolean _broadcastAfkMessage() {
return config.getBoolean("broadcast-afk-message", true);
}
@Override
public boolean areDeathMessagesEnabled() {
return config.getBoolean("death-messages", true);

View file

@ -615,8 +615,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
if (broadcast && !isHidden()) {
setDisplayNick();
final String msg = tl("userIsNotAway", getDisplayName());
if (!msg.isEmpty()) {
ess.broadcastMessage(this, msg);
final String selfmsg = tl("userIsNotAwaySelf");
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
// exclude user from receiving general AFK announcement in favor of personal message
ess.broadcastMessage(this, msg, u -> u == this);
}
if (!selfmsg.isEmpty()) {
this.sendMessage(selfmsg);
}
}
}
@ -663,8 +668,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
if (!isHidden()) {
setDisplayNick();
final String msg = tl("userIsAway", getDisplayName());
if (!msg.isEmpty()) {
ess.broadcastMessage(this, msg);
final String selfmsg = tl("userIsAwaySelf");
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
// exclude user from receiving general AFK announcement in favor of personal message
ess.broadcastMessage(this, msg, u -> u == this);
}
if (!selfmsg.isEmpty()) {
this.sendMessage(selfmsg);
}
}
}

View file

@ -56,25 +56,31 @@ public class Commandafk extends EssentialsCommand {
}
user.setDisplayNick();
String msg = "";
String selfmsg = "";
if (!user.toggleAfk(AfkStatusChangeEvent.Cause.COMMAND)) {
//user.sendMessage(_("markedAsNotAway"));
if (!user.isHidden()) {
msg = tl("userIsNotAway", user.getDisplayName());
selfmsg = tl("userIsNotAwaySelf");
}
user.updateActivity(false, AfkStatusChangeEvent.Cause.COMMAND);
} else {
//user.sendMessage(_("markedAsAway"));
if (!user.isHidden()) {
if (message != null) {
msg = tl("userIsAwayWithMessage", user.getDisplayName(), message);
selfmsg = tl("userIsAwaySelfWithMessage", message);
} else {
msg = tl("userIsAway", user.getDisplayName());
selfmsg = tl("userIsAwaySelf");
}
}
user.setAfkMessage(message);
}
if (!msg.isEmpty()) {
ess.broadcastMessage(user, msg);
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
// exclude user from receiving general AFK announcement in favor of personal message
ess.broadcastMessage(user, msg, u -> u == user);
}
if (!selfmsg.isEmpty()) {
user.sendMessage(selfmsg);
}
user.setDisplayNick(); // Set this again after toggling
}

View file

@ -437,6 +437,11 @@ sleep-ignores-afk-players: true
# You may use color codes, use {USERNAME} the player's name or {PLAYER} for the player's displayname.
afk-list-name: "none"
# When a player enters or exits AFK mode, should the AFK notification be broadcast
# to the entire server, or just to the player?
# When this setting is false, only the player will be notified upon changing their AFK state.
broadcast-afk-message: true
# You can disable the death messages of Minecraft here.
death-messages: true

View file

@ -587,6 +587,9 @@ userDoesNotExist=\u00a74The user\u00a7c {0} \u00a74does not exist.
userIsAway=\u00a77* {0} \u00a77is now AFK.
userIsAwayWithMessage=\u00a77* {0} \u00a77is now AFK.
userIsNotAway=\u00a77* {0} \u00a77is no longer AFK.
userIsAwaySelf=\u00a77You are now AFK.
userIsAwaySelfWithMessage=\u00a77You are now AFK.
userIsNotAwaySelf=\u00a77You are no longer AFK.
userJailed=\u00a76You have been jailed\!
userUnknown=\u00a74Warning\: The user ''\u00a7c{0}\u00a74'' has never joined this server.
usingTempFolderForTesting=Using temp folder for testing\: