Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add /ignore command #30

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public void assertNotNull(CommandSource source, Object value, LocaleMessage mess
assertCustom(source, value != null, message, values);
}

@SneakyThrows
public void assertNotIgnoring(CommandSource source, CommandSource ignoreSource, Player target, LocaleMessage message, Object... values) {
getUser(ignoreSource).ifPresent(u -> assertCustom(source, !u.isIgnoringPlayer(target), message, values));
}

@SneakyThrows
public void assertPermission(CommandSource source, String permission) {
assertCustom(source, source.hasPermission(permission), LocaleMessage.NO_PERMISSION);
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/me/crypnotic/neutron/api/locale/LocaleMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ public enum LocaleMessage {

FIND_MESSAGE("&b{0} &7is connected to &b{1}"),

IGNORE_AMBIGUOUS_PLAYER("&cPlayer '{0}' is ambiguous; did you mean: {1}"),
IGNORE_LIST_EMPTY("&aYou are not ignoring anyone."),
IGNORE_LIST_HEAD("&aYou are ignoring the following players:\n"),
IGNORE_LIST_ITEM("&f{0}&7, "),
IGNORE_LIST_ITEM_UNKNOWN("&f&ounknown&7, "),
IGNORE_NOW_IGNORING("&aYou are now ignoring {0}."),
IGNORE_NOW_NOT_IGNORING("&aYou are no longer ignoring {0}."),

INFO_HEADER("&l&7==> Information for player: &b{0}"),
INFO_LOCALE("&7Locale: &b{0}"),
INFO_PING("&7Ping: &b{0}"),
Expand All @@ -49,6 +57,8 @@ public enum LocaleMessage {
LIST_HEADER("&aThere are currently &b{0} &aplayers online\n&7&oHover over a server to see the players online"),
LIST_MESSAGE("&a[{0}] &e{1} player{2} online"),

MESSAGE_IGNORED_BY_TARGET("&cYou can't message {0} right now."),
MESSAGE_IGNORING_TARGET("&cYou can't message {0} because you are ignoring them."),
MESSAGE_SENDER("&b&lme \u00bb {0} &7> &o"),
MESSAGE_RECEIVER("&b&l{0} \u00bb me &7> &o"),

Expand Down
9 changes: 9 additions & 0 deletions src/main/java/me/crypnotic/neutron/api/user/User.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.crypnotic.neutron.api.user;

import java.util.Optional;
import java.util.Set;
import java.util.UUID;

import com.velocitypowered.api.command.CommandSource;
Expand All @@ -17,11 +18,19 @@ public interface User<T extends CommandSource> {
String getName();

CommandSource getReplyRecipient();

Set<UUID> getIgnoredPlayers();

Optional<UUID> getUUID();

void setReplyRecipient(CommandSource source);

void setIgnoringPlayer(Player target, boolean ignore);

default boolean isIgnoringPlayer(Player target) {
return getIgnoredPlayers().contains(target.getUniqueId());
}

default boolean isPlayer() {
return getBase().isPresent() && getBase().get() instanceof Player;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package me.crypnotic.neutron.manager.user.holder;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

import com.velocitypowered.api.command.CommandSource;
Expand Down Expand Up @@ -42,4 +44,19 @@ public void save() throws Exception {
public Optional<UUID> getUUID() {
return Optional.empty();
}

@Override
public void setIgnoringPlayer(CommandSource source) {
/* noop */
}

@Override
public Set<CommandSource> getIgnoredPlayers() {
return Collections.emptySet();
}

@Override
public boolean isIgnoringPlayer(CommandSource source) {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package me.crypnotic.neutron.manager.user.holder;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.velocitypowered.api.command.CommandSource;
import lombok.Data;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;

@ConfigSerializable
@Data
Expand All @@ -19,6 +25,17 @@ class PlayerData {
@Setting(comment = "The player's last known username.")
private String username;

@Setting(comment = "Players that this player is ignoring")
private List<UUID> ignoredPlayers = Collections.emptyList(); // Configurate includes a List TypeSerializer, so let's use that.

public Set<UUID> getIgnoredPlayers() {
return Sets.newHashSet(ignoredPlayers);
}

public void setIgnoredPlayers(Set<UUID> ignoredPlayers) {
this.ignoredPlayers = Lists.newArrayList(ignoredPlayers);
}

// Non-persisted data - this is not saved when the user is unloaded.

private WeakReference<CommandSource> replyRecipient = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import static me.crypnotic.neutron.api.Neutron.getNeutron;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

import com.google.common.collect.Sets;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;

Expand Down Expand Up @@ -67,7 +70,25 @@ public CommandSource getReplyRecipient() {
return data.getReplyRecipient();
}

@Override
public Set<UUID> getIgnoredPlayers() {
return Collections.unmodifiableSet(data.getIgnoredPlayers());
}

public void setReplyRecipient(CommandSource source) {
data.setReplyRecipient(source);
}

@Override
public void setIgnoringPlayer(Player target, boolean ignore) {
Set<UUID> newSet = Sets.newHashSet(data.getIgnoredPlayers());

if (ignore) {
newSet.add(target.getUniqueId());
} else {
newSet.remove(target.getUniqueId());
}

data.setIgnoredPlayers(Collections.unmodifiableSet(newSet));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
public enum Commands {
ALERT("alert", AlertCommand::new),
FIND("find", FindCommand::new),
IGNORE("ignore", IgnoreCommand::new),
INFO("info", InfoCommand::new),
GLIST("glist", GlistCommand::new),
MESSAGE("message", MessageCommand::new),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package me.crypnotic.neutron.module.command.options;

import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import me.crypnotic.neutron.api.command.CommandContext;
import me.crypnotic.neutron.api.command.CommandWrapper;
import me.crypnotic.neutron.api.locale.LocaleMessage;
import me.crypnotic.neutron.api.user.User;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.event.HoverEvent;

import java.util.*;
import java.util.stream.Collectors;

public class IgnoreCommand extends CommandWrapper {
@Override
public void handle(CommandSource source, CommandContext context) throws CommandExitException {
assertPermission(source, "neutron.command.ignore");
assertPlayer(source, LocaleMessage.PLAYER_ONLY_COMMAND);

if (context.size() == 0) {
handleList(source);
} else {
handleToggle(source, context);
}
}

private void handleList(CommandSource source) throws CommandExitException {
User<? extends CommandSource> user = getUser(source).get();

if (user.getIgnoredPlayers().isEmpty()) {
message(source, LocaleMessage.IGNORE_LIST_EMPTY);
return;
}

Component message = getMessage(source, LocaleMessage.IGNORE_LIST_HEAD);

for (UUID uuid : user.getIgnoredPlayers()) {
Optional<User<? extends CommandSource>> optUser = getNeutron().getUserManager().getUser(uuid);

if (optUser.isPresent()) {
User<? extends CommandSource> ignored = optUser.get();
message = message.append(getMessage(source, LocaleMessage.IGNORE_LIST_ITEM, ignored.getName()));
} else {
message = message.append(
getMessage(source, LocaleMessage.IGNORE_LIST_ITEM_UNKNOWN, uuid.toString())
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of(uuid.toString()))));
}

source.sendMessage(message);
}

}

private void handleToggle(CommandSource source, CommandContext context) throws CommandExitException {
Collection<Player> matches = getNeutron().getProxy().matchPlayer(context.get(0));
assertCustom(source, matches.size() != 0, LocaleMessage.UNKNOWN_PLAYER);
assertCustom(source, matches.size() < 2, LocaleMessage.IGNORE_AMBIGUOUS_PLAYER);
Player target = matches.stream().findFirst().get();

User<? extends CommandSource> user = getUser(source).get();

boolean newState = !user.isIgnoringPlayer(target);

if (context.size() > 1) {
newState = Boolean.parseBoolean(context.get(1));
}

user.setIgnoringPlayer(target, newState);

message(source,
user.isIgnoringPlayer(target) ? LocaleMessage.IGNORE_NOW_IGNORING : LocaleMessage.IGNORE_NOW_NOT_IGNORING,
target.getUsername());
}

@Override
public String getUsage() {
return "/ignore [player]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ public void handle(CommandSource source, CommandContext context) throws CommandE
final Optional<User<? extends CommandSource>> sender = getUser(source);
final Optional<User<? extends CommandSource>> recipient = getUser(target);

// Ensure source is not ignoring target
assertNotIgnoring(source, source, target, LocaleMessage.MESSAGE_IGNORING_TARGET, target.getUsername());

// Ensure target is not ignoring source
if (source instanceof Player && !source.hasPermission("neutron.command.message.ignore.bypass")) {
assertNotIgnoring(source, target, (Player) source, LocaleMessage.MESSAGE_IGNORED_BY_TARGET, target.getUsername());
}

UserPrivateMessageEvent event = new UserPrivateMessageEvent(sender, recipient, content, false);

getNeutron().getProxy().getEventManager().fire(event).thenAccept(resultEvent -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ public void handle(CommandSource source, CommandContext context) throws CommandE
final Optional<User<? extends CommandSource>> sender = getUser(source);
final Optional<User<? extends CommandSource>> recipient = getUser(target);

// Ensure source is not ignoring target
if (target instanceof Player) {
assertNotIgnoring(source, source, (Player) target, LocaleMessage.MESSAGE_IGNORING_TARGET, targetName);
}

// Ensure target is not ignoring source
if (source instanceof Player && !source.hasPermission("neutron.command.message.ignore.bypass")) {
assertNotIgnoring(source, target, (Player) source, LocaleMessage.MESSAGE_IGNORED_BY_TARGET, targetName);
}

UserPrivateMessageEvent event = new UserPrivateMessageEvent(sender, recipient, content, true);

getNeutron().getProxy().getEventManager().fire(event).thenAccept(resultEvent -> {
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/config.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ command {
enabled = true
aliases = ["find"]
}

ignore {
enabled = true
aliases = ["ignore", "block"]
}

info {
enabled = true
Expand Down
12 changes: 11 additions & 1 deletion src/main/resources/locales/en_US.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ connect_quit_message = "&b{0} &7left the network"

find_message = "&b{0} &7is connected to &b{1}"

ignore_ambiguous_player = "&cplayer '{0}' is ambiguous; did you mean: {1}"
ignore_list_empty = "&aYou are not ignoring anyone."
ignore_list_head = "&aYou are ignoring the following players:\n"
ignore_list_item = "&f{0}&7, "
ignore_list_item_unknown = "&f&ounknown&7, "
ignore_now_ignoring = "&aYou are now ignoring {0}."
ignore_now_not_ignoring = "&aYou are no longer ignoring {0}."

info_header = "&l&7==> Information for player = &b{0}"
info_locale = "&7Locale = &b{0}"
info_ping = "&7Ping = &b{0}"
Expand All @@ -17,6 +25,8 @@ invalid_usage = "&cUsage = {0}"
list_header = "&aThere are currently &b{0} &aplayers online\n&7&oHover over a server to see the players online"
list_message = "&a[{0}] &e{1} online"

message_ignored_by_target = "&cYou can't message {0} right now."
message_ignoring_target = "&cYou can't message {0} because you are ignoring them."
message_sender = "&b&lme » {0} &7> &o"
message_receiver = "&b&l{0} » me &7> &o"

Expand All @@ -35,4 +45,4 @@ player_only_command = "&cOnly players can use this command."
player_only_subcommand = "&cOnly players can use this subcommand."

unknown_player = "&cUnknown player = {0}"
unknown_server = "&cUnknown server = {0}"
unknown_server = "&cUnknown server = {0}"